Skip to content

Commit 8c13926

Browse files
committed
Add watermarking features and embedded font support
- Updated project file to include DejaVuSerif font as an embedded resource. - Enhanced InputParameter class with properties for watermark positioning and customization. - Modified CropOperationHandler to validate new properties for cropping. - Improved WatermarkOperationHandler to validate watermark parameters and support embedded fonts. - Updated unit tests to utilize new InputParameter properties for cropping and watermarking functionality. #3
1 parent 2819197 commit 8c13926

7 files changed

Lines changed: 66 additions & 10 deletions

src/FlowSynx.Plugins.Media.ImageProcessing.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111
<DebugType>None</DebugType>
1212
</PropertyGroup>
1313

14+
<ItemGroup>
15+
<None Remove="Fonts\DejaVuSerif.ttf" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<EmbeddedResource Include="Fonts\DejaVuSerif.ttf">
20+
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
21+
</EmbeddedResource>
22+
</ItemGroup>
23+
1424
<ItemGroup>
1525
<PackageReference Include="FlowSynx.PluginCore" Version="1.3.4" />
1626
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />

src/Fonts/DejaVuSerif.ttf

371 KB
Binary file not shown.

src/Models/InputParameter.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ internal class InputParameter
1111
public int Width { get; set; }
1212
public int Height { get; set; }
1313

14+
// Crop / Watermark
15+
public int Top { get; set; } = 10;
16+
public int Left { get; set; } = 10;
17+
1418
// Rotate
1519
public float Angle { get; set; }
1620

@@ -25,6 +29,9 @@ internal class InputParameter
2529

2630
// Watermark
2731
public string WatermarkText { get; set; } = string.Empty;
32+
public string WatermarkFontName { get; set; } = string.Empty;
33+
public int WatermarkFontSize { get; set; } = 24;
34+
public string WatermarkColor { get; set; } = "#FFFFFF";
2835

2936
public string FromColor { get; set; } = string.Empty;
3037
public string ToColor { get; set; } = string.Empty;

src/Services/CropOperationHandler.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ public void Handle(Image image, InputParameter parameter)
1111
if (parameter.Width == 0 || parameter.Height == 0)
1212
throw new ArgumentException("Crop requires positive Width and Height.");
1313

14-
image.Mutate(x => x.Crop(new Rectangle(0, 0, parameter.Width, parameter.Height)));
14+
if (parameter.Top < 0)
15+
throw new ArgumentException("Crop location top must be zero or a positive value.");
16+
17+
if (parameter.Left < 0)
18+
throw new ArgumentException("Crop location left must be zero or a positive value.");
19+
20+
image.Mutate(x => x.Crop(new Rectangle(parameter.Left, parameter.Top, parameter.Width, parameter.Height)));
1521
}
1622
}
Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using FlowSynx.Plugins.Media.ImageProcessing.Models;
1+
using FlowSynx.Plugins.Media.ImageProcessing.Helpers;
2+
using FlowSynx.Plugins.Media.ImageProcessing.Models;
3+
using SixLabors.Fonts;
24
using SixLabors.ImageSharp;
3-
using SixLabors.ImageSharp.Processing;
45
using SixLabors.ImageSharp.Drawing.Processing;
5-
using SixLabors.Fonts;
6+
using SixLabors.ImageSharp.Processing;
7+
using System.Reflection;
68

79
namespace FlowSynx.Plugins.Media.ImageProcessing.Services;
810

@@ -11,11 +13,42 @@ internal class WatermarkOperationHandler : IImageOperationHandler
1113
public void Handle(Image image, InputParameter parameter)
1214
{
1315
if (string.IsNullOrWhiteSpace(parameter.WatermarkText))
14-
throw new ArgumentException("WatermarkText is required.");
16+
throw new ArgumentException("WatermarkText must not be empty.");
17+
18+
if (parameter.WatermarkFontSize <= 0)
19+
throw new ArgumentException("Watermark font size must be greater than zero.");
20+
21+
if (parameter.Top < 0)
22+
throw new ArgumentException("Watermark location top must be zero or a positive value.");
23+
24+
if (parameter.Left < 0)
25+
throw new ArgumentException("Watermark location left must be zero or a positive value.");
26+
27+
28+
Font font;
29+
if (string.IsNullOrWhiteSpace(parameter.WatermarkFontName))
30+
{
31+
// Use embedded font as default
32+
font = LoadEmbeddedFont("FlowSynx.Plugins.Media.ImageProcessing.Fonts.DejaVuSerif.ttf", parameter.WatermarkFontSize);
33+
}
34+
else
35+
{
36+
font = SystemFonts.CreateFont(parameter.WatermarkFontName, parameter.WatermarkFontSize);
37+
}
1538

1639
image.Mutate(x => x.DrawText(parameter.WatermarkText,
17-
SystemFonts.CreateFont("Arial", 24),
18-
Color.White,
19-
new PointF(10, 10)));
40+
font,
41+
ColorHelper.ParseToRgba32(parameter.WatermarkColor),
42+
new PointF(parameter.Left, parameter.Top)));
43+
}
44+
45+
private static Font LoadEmbeddedFont(string resourceName, float fontSize)
46+
{
47+
var assembly = Assembly.GetExecutingAssembly();
48+
using Stream fontStream = assembly.GetManifestResourceStream(resourceName)
49+
?? throw new InvalidOperationException($"Font resource '{resourceName}' not found.");
50+
var fontCollection = new FontCollection();
51+
var fontFamily = fontCollection.Add(fontStream);
52+
return fontFamily.CreateFont(fontSize);
2053
}
2154
}

tests/CropOperationHandlerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public void Handle_CropsImage_WhenWidthAndHeightProvided()
1111
{
1212
var handler = new CropOperationHandler();
1313
using var image = new Image<SixLabors.ImageSharp.PixelFormats.Rgba32>(10, 10);
14-
var param = new InputParameter { Width = 5, Height = 5 };
14+
var param = new InputParameter { Width = 5, Height = 5, Left = 1, Top = 1 };
1515
handler.Handle(image, param);
1616
Assert.Equal(5, image.Width);
1717
Assert.Equal(5, image.Height);

tests/WatermarkOperationHandlerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public void Handle_AddsWatermark_WhenTextProvided()
1111
{
1212
var handler = new WatermarkOperationHandler();
1313
using var image = new Image<SixLabors.ImageSharp.PixelFormats.Rgba32>(10, 10);
14-
var param = new InputParameter { WatermarkText = "Test" };
14+
var param = new InputParameter { WatermarkText = "Test", };
1515
handler.Handle(image, param);
1616
// No exception means success
1717
}

0 commit comments

Comments
 (0)