mirror of
https://github.com/Geckon01/Watermark.Net.git
synced 2026-07-11 19:21:51 +00:00
SRP code improvements
This commit is contained in:
+26
-23
@@ -2,7 +2,8 @@ using SixLabors.Fonts;
|
|||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using Watermark.Net.src.WatermarkNet.Core;
|
using Watermark.Net.src.WatermarkNet.Core;
|
||||||
using Watermark.Net.src.WatermarkNet.Types;
|
using Watermark.Net.src.WatermarkNet.Enums;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Definitions;
|
||||||
|
|
||||||
namespace UnitTest
|
namespace UnitTest
|
||||||
{
|
{
|
||||||
@@ -13,7 +14,6 @@ namespace UnitTest
|
|||||||
public void TextWatermarkTest()
|
public void TextWatermarkTest()
|
||||||
{
|
{
|
||||||
var watermarker = new Watermarker();
|
var watermarker = new Watermarker();
|
||||||
var watermark = new TextWatermark();
|
|
||||||
|
|
||||||
var availableFont = SystemFonts.Families.FirstOrDefault();
|
var availableFont = SystemFonts.Families.FirstOrDefault();
|
||||||
if (availableFont == default)
|
if (availableFont == default)
|
||||||
@@ -21,11 +21,13 @@ namespace UnitTest
|
|||||||
throw new Exception("No available fonts found in the system");
|
throw new Exception("No available fonts found in the system");
|
||||||
}
|
}
|
||||||
|
|
||||||
watermark.Text = "Test";
|
var watermark = new TextWatermark{
|
||||||
watermark.Color = Color.White;
|
Font = availableFont.CreateFont(1),
|
||||||
watermark.Font = availableFont.CreateFont(1);
|
Text = "Test",
|
||||||
watermark.Position = Watermark.Net.src.WatermarkNet.Enums.ImagePosition.BottomCenter;
|
Style = { Color = Color.White },
|
||||||
watermark.RotateAngle = 90;
|
Layout = { Position = ImagePosition.BottomCenter , RotateAngle = 90 }
|
||||||
|
};
|
||||||
|
|
||||||
var resultedImage = watermarker.ProcessImage("TestImages/2.png", "test/text", watermark);
|
var resultedImage = watermarker.ProcessImage("TestImages/2.png", "test/text", watermark);
|
||||||
|
|
||||||
Assert.IsTrue(File.Exists(resultedImage.Path));
|
Assert.IsTrue(File.Exists(resultedImage.Path));
|
||||||
@@ -36,11 +38,12 @@ namespace UnitTest
|
|||||||
public void ImageWatermarkTest()
|
public void ImageWatermarkTest()
|
||||||
{
|
{
|
||||||
var watermarker = new Watermarker();
|
var watermarker = new Watermarker();
|
||||||
var watermark = new ImageWatermark();
|
var watermark = new ImageWatermark {
|
||||||
|
ImagePath = "TestImages/sample_wm.png",
|
||||||
|
Layout = { Position = ImagePosition.Center, Scale = 1 },
|
||||||
|
Style = { Opacity = 1 }
|
||||||
|
};
|
||||||
|
|
||||||
watermark.ImagePath = "TestImages/sample_wm.png";
|
|
||||||
watermark.Position = Watermark.Net.src.WatermarkNet.Enums.ImagePosition.Center;
|
|
||||||
watermark.Scale = 1;
|
|
||||||
var resultedImage = watermarker.ProcessImage("TestImages/2.png", "test/image", watermark);
|
var resultedImage = watermarker.ProcessImage("TestImages/2.png", "test/image", watermark);
|
||||||
|
|
||||||
Assert.IsTrue(File.Exists(resultedImage.Path));
|
Assert.IsTrue(File.Exists(resultedImage.Path));
|
||||||
@@ -51,7 +54,6 @@ namespace UnitTest
|
|||||||
public void TextWatermarkDirectoryProccessTest()
|
public void TextWatermarkDirectoryProccessTest()
|
||||||
{
|
{
|
||||||
var watermarker = new Watermarker("test/text/pave");
|
var watermarker = new Watermarker("test/text/pave");
|
||||||
var watermark = new TextWatermark();
|
|
||||||
|
|
||||||
var availableFont = SystemFonts.Families.FirstOrDefault();
|
var availableFont = SystemFonts.Families.FirstOrDefault();
|
||||||
if (availableFont == default)
|
if (availableFont == default)
|
||||||
@@ -59,12 +61,13 @@ namespace UnitTest
|
|||||||
throw new Exception("No available fonts found in the system");
|
throw new Exception("No available fonts found in the system");
|
||||||
}
|
}
|
||||||
|
|
||||||
watermark.Text = "Test";
|
var watermark = new TextWatermark {
|
||||||
watermark.Color = Rgba32.ParseHex("FFFFFF50");
|
Text = "Test",
|
||||||
watermark.Font = availableFont.CreateFont(1);
|
Font = availableFont.CreateFont(1),
|
||||||
watermark.Scale = 1f;
|
Style = { Color = Rgba32.ParseHex("FFFFFF50"), Pave = true },
|
||||||
watermark.Position = Watermark.Net.src.WatermarkNet.Enums.ImagePosition.TopLeft;
|
Layout = { Scale = 1f, Position = ImagePosition.TopLeft }
|
||||||
watermark.Pave = true;
|
};
|
||||||
|
|
||||||
watermarker.ProcessDirectory("TestImages", watermark);
|
watermarker.ProcessDirectory("TestImages", watermark);
|
||||||
|
|
||||||
Assert.IsTrue(Directory.GetFiles(watermarker.OutputDir)?.Length > 0);
|
Assert.IsTrue(Directory.GetFiles(watermarker.OutputDir)?.Length > 0);
|
||||||
@@ -74,12 +77,12 @@ namespace UnitTest
|
|||||||
public void ImageWatermarkDirectoryProccessTest()
|
public void ImageWatermarkDirectoryProccessTest()
|
||||||
{
|
{
|
||||||
var watermarker = new Watermarker("test/image/pave");
|
var watermarker = new Watermarker("test/image/pave");
|
||||||
var watermark = new ImageWatermark();
|
var watermark = new ImageWatermark {
|
||||||
|
ImagePath = "TestImages/sample_wm.png",
|
||||||
|
Layout = { Position = ImagePosition.Center, Scale = 1},
|
||||||
|
Style = { Pave = true, Opacity = 1}
|
||||||
|
};
|
||||||
|
|
||||||
watermark.ImagePath = "TestImages/sample_wm.png";
|
|
||||||
watermark.Position = Watermark.Net.src.WatermarkNet.Enums.ImagePosition.Center;
|
|
||||||
watermark.Scale = 1;
|
|
||||||
watermark.Pave = true;
|
|
||||||
watermarker.ProcessDirectory("TestImages", watermark);
|
watermarker.ProcessDirectory("TestImages", watermark);
|
||||||
|
|
||||||
Assert.IsTrue(Directory.GetFiles(watermarker.OutputDir)?.Length > 0);
|
Assert.IsTrue(Directory.GetFiles(watermarker.OutputDir)?.Length > 0);
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 18
|
||||||
VisualStudioVersion = 17.4.33213.308
|
VisualStudioVersion = 18.5.11709.299 stable
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Watermark.Net", "Watermark.Net.csproj", "{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Watermark.Net", "Watermark.Net.csproj", "{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "..\UnitTest\UnitTest.csproj", "{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "..\UnitTest\UnitTest.csproj", "{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Watrmark.Net CLI", "..\Watrmark.Net CLI\Watrmark.Net CLI.csproj", "{EC1F992E-6B68-45E7-8879-8576F728A6F3}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -23,10 +21,6 @@ Global
|
|||||||
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Release|Any CPU.Build.0 = Release|Any CPU
|
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EC1F992E-6B68-45E7-8879-8576F728A6F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EC1F992E-6B68-45E7-8879-8576F728A6F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EC1F992E-6B68-45E7-8879-8576F728A6F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EC1F992E-6B68-45E7-8879-8576F728A6F3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using SixLabors.ImageSharp.Drawing.Processing;
|
|||||||
using SixLabors.ImageSharp.PixelFormats;
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using Watermark.Net.src.WatermarkNet.Enums;
|
using Watermark.Net.src.WatermarkNet.Enums;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Definitions;
|
||||||
using Watermark.Net.src.WatermarkNet.Types;
|
using Watermark.Net.src.WatermarkNet.Types;
|
||||||
using static System.Net.Mime.MediaTypeNames;
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
@@ -36,7 +37,7 @@ namespace Watermark.Net.src.WatermarkNet.Core
|
|||||||
/// <param name="watermark">Watermark configuration.</param>
|
/// <param name="watermark">Watermark configuration.</param>
|
||||||
/// <returns>List of processed images with watermark information.</returns>
|
/// <returns>List of processed images with watermark information.</returns>
|
||||||
public List<WmarkedImage> ProcessDirectory<T>(string directory, T watermark)
|
public List<WmarkedImage> ProcessDirectory<T>(string directory, T watermark)
|
||||||
where T : WatermarkImageBase
|
where T : IWatermarkDefinition
|
||||||
{
|
{
|
||||||
List<WmarkedImage> processedImages = new List<WmarkedImage>();
|
List<WmarkedImage> processedImages = new List<WmarkedImage>();
|
||||||
foreach (var imageFile in Directory.GetFiles(directory))
|
foreach (var imageFile in Directory.GetFiles(directory))
|
||||||
@@ -80,8 +81,8 @@ namespace Watermark.Net.src.WatermarkNet.Core
|
|||||||
using (var targetImage = Image.Load(imagePath))
|
using (var targetImage = Image.Load(imagePath))
|
||||||
using (var watermarkImage = Image.Load(watermark.ImagePath))
|
using (var watermarkImage = Image.Load(watermark.ImagePath))
|
||||||
{
|
{
|
||||||
var scaledWmWidth = (int)Math.Round(watermarkImage.Width * watermark.Scale);
|
var scaledWmWidth = (int)Math.Round(watermarkImage.Width * watermark.Layout.Scale);
|
||||||
var scaledWmHeight = (int)Math.Round(watermarkImage.Height * watermark.Scale);
|
var scaledWmHeight = (int)Math.Round(watermarkImage.Height * watermark.Layout.Scale);
|
||||||
watermarkImage.Mutate(x => x.Resize(new Size(scaledWmWidth, scaledWmHeight)));
|
watermarkImage.Mutate(x => x.Resize(new Size(scaledWmWidth, scaledWmHeight)));
|
||||||
|
|
||||||
using (var markedImage = targetImage.Clone(ctx => this.ApplyScalingWaterMarkImage(ctx, watermark, watermarkImage, targetImage)))
|
using (var markedImage = targetImage.Clone(ctx => this.ApplyScalingWaterMarkImage(ctx, watermark, watermarkImage, targetImage)))
|
||||||
@@ -255,32 +256,32 @@ namespace Watermark.Net.src.WatermarkNet.Core
|
|||||||
float scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);
|
float scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);
|
||||||
|
|
||||||
// Create a new font
|
// Create a new font
|
||||||
SixLabors.Fonts.Font scaledFont = new SixLabors.Fonts.Font(watermark.Font, scalingFactor / 16 * (watermark.Font.Size * watermark.Scale));
|
SixLabors.Fonts.Font scaledFont = new SixLabors.Fonts.Font(watermark.Font, scalingFactor / 16 * (watermark.Font.Size * watermark.Layout.Scale));
|
||||||
//processingContext.SetGraphicsOptions(new GraphicsOptions { AlphaCompositionMode = SixLabors.ImageSharp.PixelFormats.PixelAlphaCompositionMode.Clear});
|
//processingContext.SetGraphicsOptions(new GraphicsOptions { AlphaCompositionMode = SixLabors.ImageSharp.PixelFormats.PixelAlphaCompositionMode.Clear});
|
||||||
//If set, apply backround color
|
//If set, apply backround color
|
||||||
if (watermark.BackroundColor != null)
|
if (watermark.Style.Color != null)
|
||||||
processingContext.BackgroundColor((Color)watermark.BackroundColor);
|
processingContext.BackgroundColor((Color)watermark.Style.Color);
|
||||||
|
|
||||||
var textOptions = new RichTextOptions(scaledFont)
|
var textOptions = new RichTextOptions(scaledFont)
|
||||||
{
|
{
|
||||||
ColorFontSupport = ColorFontSupport.MicrosoftColrFormat,
|
ColorFontSupport = ColorFontSupport.MicrosoftColrFormat,
|
||||||
Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, watermark.Position),
|
Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, watermark.Layout.Position),
|
||||||
HorizontalAlignment = HorizontalAlignmentFromPosition(watermark.Position),
|
HorizontalAlignment = HorizontalAlignmentFromPosition(watermark.Layout.Position),
|
||||||
VerticalAlignment = VerticalAlignment.Top,
|
VerticalAlignment = VerticalAlignment.Top,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (watermark.Pave)
|
if (watermark.Style.Pave)
|
||||||
{
|
{
|
||||||
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
||||||
{
|
{
|
||||||
textOptions.Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, position);
|
textOptions.Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, position);
|
||||||
textOptions.HorizontalAlignment = HorizontalAlignmentFromPosition(position);
|
textOptions.HorizontalAlignment = HorizontalAlignmentFromPosition(position);
|
||||||
processingContext.DrawText(textOptions, watermark.Text, watermark.Color);
|
processingContext.DrawText(textOptions, watermark.Text, watermark.Style.Color);
|
||||||
}
|
}
|
||||||
return processingContext;
|
return processingContext;
|
||||||
}
|
}
|
||||||
return processingContext
|
return processingContext
|
||||||
.DrawText(textOptions, watermark.Text, watermark.Color);
|
.DrawText(textOptions, watermark.Text, watermark.Style.Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -311,20 +312,20 @@ namespace Watermark.Net.src.WatermarkNet.Core
|
|||||||
: watermarkImage.Height / scaleFactor;
|
: watermarkImage.Height / scaleFactor;
|
||||||
|
|
||||||
//If set, apply backround color
|
//If set, apply backround color
|
||||||
if (watermark.BackroundColor != null)
|
if (watermark.Style.Color != null)
|
||||||
processingContext.BackgroundColor((Color)watermark.BackroundColor);
|
processingContext.BackgroundColor((Color)watermark.Style.Color);
|
||||||
|
|
||||||
watermarkImage.Mutate(x => x.Resize(new Size((int)scaledWmWidth, (int)scaledWmHeight)));
|
watermarkImage.Mutate(x => x.Resize(new Size((int)scaledWmWidth, (int)scaledWmHeight)));
|
||||||
var wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, watermark.Position);
|
var wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, watermark.Layout.Position);
|
||||||
|
|
||||||
if (watermark.Pave)
|
if (watermark.Style.Pave)
|
||||||
{
|
{
|
||||||
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
||||||
{
|
{
|
||||||
wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, position);
|
wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, position);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Opacity);
|
processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Style.Opacity);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -334,7 +335,7 @@ namespace Watermark.Net.src.WatermarkNet.Core
|
|||||||
return processingContext;
|
return processingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
return processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Opacity);
|
return processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Style.Opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Layout;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Styling;
|
||||||
|
|
||||||
|
namespace Watermark.Net.src.WatermarkNet.Models.Definitions
|
||||||
|
{
|
||||||
|
public interface IWatermarkDefinition
|
||||||
|
{
|
||||||
|
WatermarkLayout Layout { get; }
|
||||||
|
WatermarkStyle Style { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Layout;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Styling;
|
||||||
|
|
||||||
|
namespace Watermark.Net.src.WatermarkNet.Models.Definitions
|
||||||
|
{
|
||||||
|
public class ImageWatermark : IWatermarkDefinition
|
||||||
|
{
|
||||||
|
public required string ImagePath { get; init; }
|
||||||
|
|
||||||
|
public WatermarkLayout Layout
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
init;
|
||||||
|
} = new();
|
||||||
|
|
||||||
|
|
||||||
|
public WatermarkStyle Style
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
init;
|
||||||
|
} = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using SixLabors.Fonts;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Layout;
|
||||||
|
using Watermark.Net.src.WatermarkNet.Models.Styling;
|
||||||
|
|
||||||
|
namespace Watermark.Net.src.WatermarkNet.Models.Definitions
|
||||||
|
{
|
||||||
|
public class TextWatermark : IWatermarkDefinition
|
||||||
|
{
|
||||||
|
public required string Text { get; set; }
|
||||||
|
|
||||||
|
public required Font Font { get; set; }
|
||||||
|
|
||||||
|
public WatermarkLayout Layout { get; init; }
|
||||||
|
= new();
|
||||||
|
|
||||||
|
public WatermarkStyle Style { get; init; }
|
||||||
|
= new();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
using Watermark.Net.src.WatermarkNet.Enums;
|
||||||
|
|
||||||
|
namespace Watermark.Net.src.WatermarkNet.Models.Layout
|
||||||
|
{
|
||||||
|
public class WatermarkLayout
|
||||||
|
{
|
||||||
|
public ImagePosition Position { get; set; }
|
||||||
|
|
||||||
|
public float Scale { get; set; }
|
||||||
|
|
||||||
|
public int RotateAngle { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the padding space around the watermark in pixels.
|
||||||
|
/// Default: 10px
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Thrown when value is negative.</exception>
|
||||||
|
public float Padding { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using SixLabors.Fonts;
|
||||||
|
using SixLabors.ImageSharp;
|
||||||
|
|
||||||
|
namespace Watermark.Net.src.WatermarkNet.Models.Styling
|
||||||
|
{
|
||||||
|
public class WatermarkStyle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the transparency level of the watermark.
|
||||||
|
/// Range: 0.0 (fully transparent) to 1.0 (completely opaque).
|
||||||
|
/// Default: 1.0
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentOutOfRangeException">
|
||||||
|
/// Thrown when value is outside the 0.0-1.0 range.
|
||||||
|
/// </exception>
|
||||||
|
public float Opacity { get; set; }
|
||||||
|
|
||||||
|
public bool Pave { get; set; }
|
||||||
|
public Color Color { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Watermark.Net.src.WatermarkNet.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a configurable image-based watermark with scaling, positioning, and transparency controls.
|
|
||||||
/// </summary>
|
|
||||||
public class ImageWatermark : WatermarkImageBase
|
|
||||||
{
|
|
||||||
private string _imagePath;
|
|
||||||
private float? _opacity;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the absolute path to the watermark image file.
|
|
||||||
/// Supported formats: PNG, JPEG, BMP, GIF.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="FileNotFoundException">
|
|
||||||
/// Thrown when setting a value that doesn't point to an existing file.
|
|
||||||
/// </exception>
|
|
||||||
public string ImagePath
|
|
||||||
{
|
|
||||||
get => _imagePath;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (!File.Exists(value))
|
|
||||||
throw new FileNotFoundException("Watermark image not found", value);
|
|
||||||
|
|
||||||
_imagePath = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the transparency level of the watermark.
|
|
||||||
/// Range: 0.0 (fully transparent) to 1.0 (completely opaque).
|
|
||||||
/// Default: 1.0
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException">
|
|
||||||
/// Thrown when value is outside the 0.0-1.0 range.
|
|
||||||
/// </exception>
|
|
||||||
public float Opacity
|
|
||||||
{
|
|
||||||
get => _opacity ?? 1f;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value < 0 || value > 1)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(Opacity),
|
|
||||||
"Opacity must be between 0.0 and 1.0");
|
|
||||||
|
|
||||||
_opacity = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the scale factor applied to the watermark image relative to the target image.
|
|
||||||
/// Default: 0.2 (20% of target image width)
|
|
||||||
/// </summary>
|
|
||||||
public float Scale { get; set; } = 0.2f;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the ImageWatermark class with specified image path.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="imagePath">Path to the watermark image file.</param>
|
|
||||||
public ImageWatermark(string imagePath) : this()
|
|
||||||
{
|
|
||||||
ImagePath = imagePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the ImageWatermark class with default values.
|
|
||||||
/// </summary>
|
|
||||||
public ImageWatermark() { }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
using SixLabors.Fonts;
|
|
||||||
using SixLabors.ImageSharp;
|
|
||||||
|
|
||||||
namespace Watermark.Net.src.WatermarkNet.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a configurable text-based watermark with styling, positioning, and rendering options.
|
|
||||||
/// </summary>
|
|
||||||
public class TextWatermark : WatermarkImageBase
|
|
||||||
{
|
|
||||||
private string _text;
|
|
||||||
private Font _font;
|
|
||||||
private float _padding;
|
|
||||||
private Color _color;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the color of the text watermark.
|
|
||||||
/// Default: White (#FFFFFF)
|
|
||||||
/// </summary>
|
|
||||||
public Color Color
|
|
||||||
{
|
|
||||||
get => _color;
|
|
||||||
set => _color = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the text content for the watermark.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException">Thrown when value is null or whitespace.</exception>
|
|
||||||
public string Text
|
|
||||||
{
|
|
||||||
get => _text;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(value))
|
|
||||||
throw new ArgumentException("Watermark text cannot be empty", nameof(Text));
|
|
||||||
_text = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the font used to render the text watermark.
|
|
||||||
/// Default: Arial 12pt
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentNullException">Thrown when value is null.</exception>
|
|
||||||
public Font Font
|
|
||||||
{
|
|
||||||
get => _font;
|
|
||||||
set => _font = value ?? throw new ArgumentNullException(nameof(Font));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the padding space around the text watermark in pixels.
|
|
||||||
/// Default: 10px
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when value is negative.</exception>
|
|
||||||
public float Padding
|
|
||||||
{
|
|
||||||
get => _padding;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (value < 0) throw new ArgumentOutOfRangeException(nameof(Padding), "Padding cannot be negative");
|
|
||||||
_padding = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the rotation angle for the text watermark in degrees.
|
|
||||||
/// Default: 0 (no rotation)
|
|
||||||
/// </summary>
|
|
||||||
public float Rotation { get; set; } = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the TextWatermark class with default values.
|
|
||||||
/// </summary>
|
|
||||||
public TextWatermark()
|
|
||||||
{
|
|
||||||
var availableFont = SystemFonts.Families.FirstOrDefault();
|
|
||||||
if (availableFont == default)
|
|
||||||
{
|
|
||||||
throw new Exception("No available fonts found in the system");
|
|
||||||
}
|
|
||||||
_color = Color.White;
|
|
||||||
_font = availableFont.CreateFont(1);
|
|
||||||
_padding = 10f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
using SixLabors.ImageSharp;
|
|
||||||
using Watermark.Net.src.WatermarkNet.Enums;
|
|
||||||
|
|
||||||
namespace Watermark.Net.src.WatermarkNet.Types
|
|
||||||
{
|
|
||||||
public class WatermarkImageBase
|
|
||||||
{
|
|
||||||
protected ImagePosition _postion;
|
|
||||||
protected float _scale;
|
|
||||||
protected int _rotateAngle;
|
|
||||||
protected bool _pave;
|
|
||||||
protected Color? _backround;
|
|
||||||
|
|
||||||
public ImagePosition Position
|
|
||||||
{
|
|
||||||
get { return _postion; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_postion= value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public float Scale
|
|
||||||
{
|
|
||||||
get { return _scale; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if(value <= 0) { throw new ArgumentOutOfRangeException("Scale", "Image scale can not be less or equal zero."); }
|
|
||||||
_scale= value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RotateAngle
|
|
||||||
{
|
|
||||||
get { return _rotateAngle; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (Math.Abs(value) > 180) { throw new ArgumentOutOfRangeException("RotateAngle", "Image rotate angle can not be larger than 180°."); }
|
|
||||||
_rotateAngle= value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Pave
|
|
||||||
{
|
|
||||||
get { return _pave; }
|
|
||||||
set { _pave = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color? BackroundColor
|
|
||||||
{
|
|
||||||
get { return _backround; }
|
|
||||||
set { _backround = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public WatermarkImageBase()
|
|
||||||
{
|
|
||||||
_scale= 1.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user