Skip to content

Commit

Permalink
Merge pull request #12 from EdiWang/dev/refact
Browse files Browse the repository at this point in the history
Refact
  • Loading branch information
EdiWang authored Aug 11, 2024
2 parents 86270d4 + fb58c1f commit aa10576
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 47 deletions.
4 changes: 2 additions & 2 deletions src/Edi.ImageWatermark/Edi.ImageWatermark.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>2.13.0</Version>
<Version>2.14.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Company>edi.wang</Company>
<Authors>Edi Wang</Authors>
Expand Down
104 changes: 59 additions & 45 deletions src/Edi.ImageWatermark/ImageWatermarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public class ImageWatermarker : IDisposable, IImageWatermarker

public ImageWatermarker(Stream originImageStream, string imgExtensionName, int pixelsThreshold = 0)
{
_originImageStream = originImageStream;
_imgExtensionName = imgExtensionName;
_originImageStream = originImageStream ?? throw new ArgumentNullException(nameof(originImageStream));
_imgExtensionName = imgExtensionName ?? throw new ArgumentNullException(nameof(imgExtensionName));

if (pixelsThreshold > 0)
{
Expand All @@ -45,6 +45,8 @@ public MemoryStream AddWatermark(string watermarkText, Color color,
int fontSize = 20,
Font font = null)
{
if (string.IsNullOrEmpty(watermarkText)) throw new ArgumentNullException(nameof(watermarkText));

using var img = Image.Load(_originImageStream);
if (_skipImageSize && img.Height * img.Width < _pixelsThreshold)
{
Expand All @@ -53,63 +55,75 @@ public MemoryStream AddWatermark(string watermarkText, Color color,

var watermarkedStream = new MemoryStream();

string fontName = string.Empty;
string fontName = GetFontName();
var f = font ?? SystemFonts.CreateFont(fontName, fontSize, FontStyle.Bold);
var textSize = TextMeasurer.MeasureBounds(watermarkText, new TextOptions(f));
var (x, y) = GetWatermarkPosition(watermarkPosition, img.Width, img.Height, textSize.Width, textSize.Height, textPadding);

img.Mutate(ctx => ctx.DrawText(watermarkText, f, color, new PointF(x, y)));

SaveImage(img, watermarkedStream);

return watermarkedStream;
}

private string GetFontName()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
fontName = "Arial";
return "Arial";
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
fontName = GetAvailableFontForLinux();
return GetAvailableFontForLinux();
}

var f = font ?? SystemFonts.CreateFont(fontName, fontSize, FontStyle.Bold);
var textSize = TextMeasurer.MeasureBounds(watermarkText, new TextOptions(f));
int x, y;
throw new PlatformNotSupportedException("Unsupported platform");
}

switch (watermarkPosition)
private static (int x, int y) GetWatermarkPosition(WatermarkPosition position, int imgWidth, int imgHeight, float textWidth, float textHeight, int padding)
{
return position switch
{
case WatermarkPosition.TopLeft:
x = textPadding; y = textPadding;
break;
case WatermarkPosition.TopRight:
x = img.Width - (int)textSize.Width - textPadding;
y = textPadding;
break;
case WatermarkPosition.BottomLeft:
x = textPadding;
y = img.Height - (int)textSize.Height - textPadding;
break;
case WatermarkPosition.BottomRight:
x = img.Width - (int)textSize.Width - textPadding;
y = img.Height - (int)textSize.Height - textPadding;
break;
default:
x = textPadding; y = textPadding;
break;
}

img.Mutate(ctx => ctx.DrawText(watermarkText, f, color, new PointF(x, y)));
WatermarkPosition.TopLeft => (padding, padding),
WatermarkPosition.TopRight => (imgWidth - (int)textWidth - padding, padding),
WatermarkPosition.BottomLeft => (padding, imgHeight - (int)textHeight - padding),
WatermarkPosition.BottomRight => (imgWidth - (int)textWidth - padding, imgHeight - (int)textHeight - padding),
_ => (padding, padding)
};
}

switch (_imgExtensionName)
private void SaveImage(Image img, MemoryStream stream)
{
try
{
case ".png":
img.SaveAsPng(watermarkedStream);
break;
case ".jpg":
case ".jpeg":
img.SaveAsJpeg(watermarkedStream);
break;
case ".bmp":
img.SaveAsBmp(watermarkedStream);
break;
switch (_imgExtensionName.ToLower())
{
case ".png":
img.SaveAsPng(stream);
break;
case ".jpg":
case ".jpeg":
img.SaveAsJpeg(stream);
break;
case ".bmp":
img.SaveAsBmp(stream);
break;
default:
throw new NotSupportedException($"Unsupported image format: {_imgExtensionName}");
}
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to save image", ex);
}

return watermarkedStream;
}

public void Dispose() => _originImageStream?.Dispose();
public void Dispose()
{
_originImageStream?.Dispose();
}

private static string GetAvailableFontForLinux()
{
Expand All @@ -126,6 +140,6 @@ private static string GetAvailableFontForLinux()
"DejaVu Sans",
"DejaVu Sans Mono"
};
return fontList.FirstOrDefault(fontName => SystemFonts.Collection.TryGet(fontName, out _));
return fontList.FirstOrDefault(fontName => SystemFonts.Collection.TryGet(fontName, out _)) ?? "Arial";
}
}

0 comments on commit aa10576

Please sign in to comment.