mirror of
https://github.com/Geckon01/Watermark.Net.git
synced 2026-06-17 00:27:47 +00:00
First commit
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\watermark.net.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:watermark.net.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\watermark.net.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:watermark.net.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.common\\watermarker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.common\\watermarker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\sourceimage.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\sourceimage.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\imagewatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\imagewatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\textwatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\textwatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
"VerticalTabListWidth": 256,
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": 0,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "Watermark.Net.csproj",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeDocumentMoniker": "Watermark.Net.csproj",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeToolTip": "Watermark.Net.csproj",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
|
||||
"WhenOpened": "2025-07-23T00:08:42.641Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "ImageWatermark.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"ViewState": "AgIAAA4AAAAAAAAAAAAQwEMAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:18:31.318Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "SourceImage.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:18:29.952Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Watermark.Net",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeDocumentMoniker": "Watermark.Net.csproj",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeToolTip": "Watermark.Net.csproj",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
|
||||
"WhenOpened": "2025-07-22T00:16:02.548Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"Title": "UnitTest.cs",
|
||||
"DocumentMoniker": "D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"RelativeDocumentMoniker": "..\\..\\..\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"ToolTip": "D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"RelativeToolTip": "..\\..\\..\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"ViewState": "AgIAABgAAAAAAAAAAADgvyYAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:10:06.88Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"Title": "TextWatermark.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"ViewState": "AgIAABoAAAAAAAAAAAAUwFIAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-21T23:58:35.959Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "Watermarker.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAAcAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-15T22:39:18.693Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\watermark.net.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:watermark.net.csproj||{FA3CD31E-987B-443A-9B81-186104E8DAC1}|"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\watermark.net.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:watermark.net.csproj||{04B8AB82-A572-4FEF-95CE-5222444B6B64}|"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.common\\watermarker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.common\\watermarker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\sourceimage.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\sourceimage.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\imagewatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\imagewatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|d:\\dev\\getready\\watermark.net\\watermark.net\\src\\watermarknet.types\\textwatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}|Watermark.Net.csproj|solutionrelative:src\\watermarknet.types\\textwatermark.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
"VerticalTabListWidth": 256,
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": 0,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "Watermark.Net.csproj",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeDocumentMoniker": "Watermark.Net.csproj",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeToolTip": "Watermark.Net.csproj",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
|
||||
"WhenOpened": "2025-07-23T00:08:42.641Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "ImageWatermark.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\ImageWatermark.cs",
|
||||
"ViewState": "AgIAAA4AAAAAAAAAAAAQwEMAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:18:31.318Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "SourceImage.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\SourceImage.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:18:29.952Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "Watermark.Net",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeDocumentMoniker": "Watermark.Net.csproj",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\Watermark.Net.csproj",
|
||||
"RelativeToolTip": "Watermark.Net.csproj",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000758|",
|
||||
"WhenOpened": "2025-07-22T00:16:02.548Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 6,
|
||||
"Title": "UnitTest.cs",
|
||||
"DocumentMoniker": "D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"RelativeDocumentMoniker": "..\\..\\..\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"ToolTip": "D:\\dev\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"RelativeToolTip": "..\\..\\..\\Watermark.NET\\UnitTest\\UnitTest.cs",
|
||||
"ViewState": "AgIAABgAAAAAAAAAAADgvyYAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-22T00:10:06.88Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 5,
|
||||
"Title": "TextWatermark.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Types\\TextWatermark.cs",
|
||||
"ViewState": "AgIAABoAAAAAAAAAAAAUwFIAAAABAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-21T23:58:35.959Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "Watermarker.cs",
|
||||
"DocumentMoniker": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"RelativeDocumentMoniker": "src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"ToolTip": "D:\\dev\\GetReady\\Watermark.Net\\Watermark.Net\\src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"RelativeToolTip": "src\\WatermarkNet.Common\\Watermarker.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAAcAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-07-15T22:39:18.693Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||
<AssemblyVersion>0.25.7.23</AssemblyVersion>
|
||||
<Title>Waternark.NET</Title>
|
||||
<Authors>Geckon01</Authors>
|
||||
<Description>Watermark.Net is .NET library for adding text and image watermarks to images. Built on SixLabors.ImageSharp, it provides a simple yet comprehensive API for all your watermarking needs.</Description>
|
||||
<FileVersion>0.25.7.23</FileVersion>
|
||||
<Version>0.25.7.23</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33213.308
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Watermark.Net", "Watermark.Net.csproj", "{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "..\UnitTest\UnitTest.csproj", "{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample", "..\Sample\Sample.csproj", "{E28B3D42-E65D-4178-A25B-8B76FC6F9673}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Watrmark.Net CLI", "..\Watrmark.Net CLI\Watrmark.Net CLI.csproj", "{EC1F992E-6B68-45E7-8879-8576F728A6F3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5000C6D8-A7CD-4815-A724-EEE51AD8AFDA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26E6D8A0-CFB1-4A30-A4DD-D6DBBDADB388}.Debug|Any CPU.ActiveCfg = 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.Build.0 = Release|Any CPU
|
||||
{E28B3D42-E65D-4178-A25B-8B76FC6F9673}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E28B3D42-E65D-4178-A25B-8B76FC6F9673}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E28B3D42-E65D-4178-A25B-8B76FC6F9673}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E28B3D42-E65D-4178-A25B-8B76FC6F9673}.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
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BDD35E29-9EA2-4833-B2F4-26E051B7AF10}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,342 @@
|
||||
using SixLabors.Fonts;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Watermark.Net.src.WatermarkNet.Enums;
|
||||
using Watermark.Net.src.WatermarkNet.Types;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace Watermark.Net.src.WatermarkNet.Core
|
||||
{
|
||||
public class Watermarker
|
||||
{
|
||||
private string _outputDir;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the output directory for processed images.
|
||||
/// </summary>
|
||||
public string OutputDir { get { return _outputDir; } set { _outputDir = value; } }
|
||||
public Watermarker()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Watermarker(string outputDir)
|
||||
{
|
||||
_outputDir = outputDir;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes all images in a directory applying watermark.
|
||||
/// </summary>
|
||||
/// <param name="directory">Source directory containing images to process.</param>
|
||||
/// <param name="watermark">Watermark configuration.</param>
|
||||
/// <returns>List of processed images with watermark information.</returns>
|
||||
public List<WmarkedImage> ProcessDirectory<T>(string directory, T watermark)
|
||||
where T : WatermarkImageBase
|
||||
{
|
||||
List<WmarkedImage> processedImages = new List<WmarkedImage>();
|
||||
foreach (var imageFile in Directory.GetFiles(directory))
|
||||
{
|
||||
//Do not process directories and hidden files
|
||||
if (File.GetAttributes(imageFile).HasFlag(FileAttributes.Directory) || File.GetAttributes(imageFile).HasFlag(FileAttributes.Hidden))
|
||||
continue;
|
||||
|
||||
WmarkedImage? resultedImage = null;
|
||||
if (typeof(T).IsAssignableTo(typeof(ImageWatermark)))
|
||||
{
|
||||
var concreateWatermark = (ImageWatermark)Convert.ChangeType(watermark, typeof(ImageWatermark));
|
||||
resultedImage = ProcessImage(imageFile, this.OutputDir, concreateWatermark);
|
||||
}
|
||||
if (typeof(T).IsAssignableTo(typeof(TextWatermark)))
|
||||
{
|
||||
var concreateWatermark = (TextWatermark)Convert.ChangeType(watermark, typeof(TextWatermark));
|
||||
resultedImage = ProcessImage(imageFile, this.OutputDir, concreateWatermark);
|
||||
}
|
||||
if (resultedImage != null)
|
||||
processedImages.Add(resultedImage);
|
||||
}
|
||||
return processedImages;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies an image watermark to a single image.
|
||||
/// </summary>
|
||||
/// <param name="imagePath">Path to source image file.</param>
|
||||
/// <param name="outputDirectory">Output directory for processed image.</param>
|
||||
/// <param name="watermark">Image watermark configuration.</param>
|
||||
/// <returns>Processed image information or null on failure.</returns>
|
||||
/// <exception cref="FileNotFoundException">Thrown when source image or watermark image is missing.</exception>
|
||||
public WmarkedImage? ProcessImage(string imagePath, string outputDirectory, ImageWatermark watermark)
|
||||
{
|
||||
if (!File.Exists(imagePath)) { throw new FileNotFoundException("Source file not found!", imagePath); }
|
||||
if (!File.Exists(watermark.ImagePath)) { throw new FileNotFoundException("Watermark file not found!", imagePath); }
|
||||
if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); }
|
||||
|
||||
WmarkedImage? resultedImage = null;
|
||||
using (var targetImage = Image.Load(imagePath))
|
||||
using (var watermarkImage = Image.Load(watermark.ImagePath))
|
||||
{
|
||||
var scaledWmWidth = (int)Math.Round(watermarkImage.Width * watermark.Scale);
|
||||
var scaledWmHeight = (int)Math.Round(watermarkImage.Height * watermark.Scale);
|
||||
watermarkImage.Mutate(x => x.Resize(new Size(scaledWmWidth, scaledWmHeight)));
|
||||
|
||||
using (var markedImage = targetImage.Clone(ctx => this.ApplyScalingWaterMarkImage(ctx, watermark, watermarkImage, targetImage)))
|
||||
{
|
||||
resultedImage = new WmarkedImage(markedImage, outputDirectory + Path.DirectorySeparatorChar + Path.GetFileName(imagePath));
|
||||
markedImage.Save(resultedImage.Path);
|
||||
}
|
||||
}
|
||||
return resultedImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies a text watermark to a single image.
|
||||
/// </summary>
|
||||
/// <param name="imagePath">Path to source image file.</param>
|
||||
/// <param name="outputDirectory">Output directory for processed image.</param>
|
||||
/// <param name="watermark">Text watermark configuration.</param>
|
||||
/// <returns>Processed image information or null on failure.</returns>
|
||||
/// <exception cref="FileNotFoundException">Thrown when source image is missing.</exception>
|
||||
public WmarkedImage? ProcessImage(string imagePath, string outputDirectory, TextWatermark watermark)
|
||||
{
|
||||
if(!File.Exists(imagePath)) { throw new FileNotFoundException("Source file not found!", imagePath); }
|
||||
if (!Directory.Exists(outputDirectory)) { Directory.CreateDirectory(outputDirectory); }
|
||||
|
||||
WmarkedImage? resultedImage = null;
|
||||
using (var targetImage = Image.Load(imagePath))
|
||||
{
|
||||
using (var markedImage = targetImage.Clone(ctx => this.ApplyScalingWaterMarkText(ctx, watermark)))
|
||||
{
|
||||
resultedImage = new WmarkedImage(markedImage, outputDirectory + Path.DirectorySeparatorChar + Path.GetFileName(imagePath));
|
||||
markedImage.Save(resultedImage.Path);
|
||||
}
|
||||
}
|
||||
return resultedImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates origin point for text watermark based on position and size.
|
||||
/// </summary>
|
||||
/// <param name="width">Target image width.</param>
|
||||
/// <param name="height">Target image height.</param>
|
||||
/// <param name="watermarkSize">Watermark text size.</param>
|
||||
/// <param name="position">Position on target image.</param>
|
||||
/// <returns>Calculated origin point coordinates.</returns>
|
||||
private PointF CalcWatermarkOrigin(int width, int height, float watermarkSize, ImagePosition position)
|
||||
{
|
||||
var origin = new PointF(0, 0);
|
||||
//Static value 1 pt is 72 px per inch
|
||||
var pixelsPerInch = 72;
|
||||
var wmHeight = watermarkSize / pixelsPerInch;
|
||||
|
||||
switch (position)
|
||||
{
|
||||
case ImagePosition.TopLeft:
|
||||
origin = new PointF(watermarkSize / 2, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.TopCenter:
|
||||
origin = new PointF(width / 2, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.TopRight:
|
||||
origin = new PointF(width - watermarkSize * 2, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.CenterLeft:
|
||||
origin = new PointF(watermarkSize / 2, height / 2.5f);
|
||||
break;
|
||||
case ImagePosition.Center:
|
||||
origin = new PointF(width / 2, height / 2.5f);
|
||||
break;
|
||||
case ImagePosition.CenterRight:
|
||||
origin = new PointF(width - watermarkSize * 2, height / 2.5f);
|
||||
break;
|
||||
case ImagePosition.BottomLeft:
|
||||
origin = new PointF(watermarkSize / 2, height - watermarkSize * 2);
|
||||
break;
|
||||
case ImagePosition.BottomCenter:
|
||||
origin = new PointF(width / 2, height - watermarkSize * 2);
|
||||
break;
|
||||
case ImagePosition.BottomRight:
|
||||
origin = new PointF(width - watermarkSize * 2, height - watermarkSize * 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates origin point for image watermark based on position and dimensions.
|
||||
/// </summary>
|
||||
/// <param name="width">Target image width.</param>
|
||||
/// <param name="height">Target image height.</param>
|
||||
/// <param name="wmWidth">Watermark image width.</param>
|
||||
/// <param name="wmHeight">Watermark image height.</param>
|
||||
/// <param name="position">Position on target image.</param>
|
||||
/// <returns>Calculated origin point coordinates.</returns>
|
||||
private Point CalcWatermarkOrigin(int width, int height, int wmWidth,int wmHeight, ImagePosition position)
|
||||
{
|
||||
var origin = new Point(0, 0);
|
||||
|
||||
var wmPaddingX = width - wmWidth;
|
||||
var paddingSide = wmPaddingX / 2;
|
||||
|
||||
switch (position)
|
||||
{
|
||||
case ImagePosition.TopLeft:
|
||||
origin = new Point(wmWidth / 2, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.TopCenter:
|
||||
origin = new Point((int)paddingSide, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.TopRight:
|
||||
origin = new Point(width - wmWidth * 2, wmHeight / 2);
|
||||
break;
|
||||
case ImagePosition.CenterLeft:
|
||||
origin = new Point(wmWidth / 2, height / 2);
|
||||
break;
|
||||
case ImagePosition.Center:
|
||||
origin = new Point((int)paddingSide, (int)(height / 2));
|
||||
break;
|
||||
case ImagePosition.CenterRight:
|
||||
origin = new Point(width - wmWidth * 2, height / 2);
|
||||
break;
|
||||
case ImagePosition.BottomLeft:
|
||||
origin = new Point(wmWidth / 2, height - wmHeight);
|
||||
break;
|
||||
case ImagePosition.BottomCenter:
|
||||
origin = new Point((int)paddingSide, height - wmHeight);
|
||||
break;
|
||||
case ImagePosition.BottomRight:
|
||||
origin = new Point(width - wmWidth * 2, height - wmHeight);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return origin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines horizontal alignment based on watermark position.
|
||||
/// </summary>
|
||||
/// <param name="imagePosition">Watermark position on image.</param>
|
||||
/// <returns>Corresponding horizontal alignment setting.</returns>
|
||||
private HorizontalAlignment HorizontalAlignmentFromPosition(ImagePosition imagePosition)
|
||||
{
|
||||
switch (imagePosition)
|
||||
{
|
||||
case ImagePosition.TopCenter:
|
||||
return HorizontalAlignment.Center;
|
||||
break;
|
||||
case ImagePosition.Center:
|
||||
return HorizontalAlignment.Center;
|
||||
break;
|
||||
case ImagePosition.BottomCenter:
|
||||
return HorizontalAlignment.Center;
|
||||
break;
|
||||
}
|
||||
return HorizontalAlignment.Left;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies text watermark to image with automatic scaling and positioning.
|
||||
/// </summary>
|
||||
/// <param name="processingContext">Image processing context.</param>
|
||||
/// <param name="watermark">Text watermark configuration.</param>
|
||||
/// <returns>Processing context with applied watermark.</returns>
|
||||
private IImageProcessingContext ApplyScalingWaterMarkText(IImageProcessingContext processingContext, TextWatermark watermark)
|
||||
{
|
||||
Size imgSize = processingContext.GetCurrentSize();
|
||||
FontRectangle size = TextMeasurer.MeasureSize(watermark.Text, new TextOptions(watermark.Font));
|
||||
|
||||
// Find out how much we need to scale the text to fill the space (up or down)
|
||||
float scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);
|
||||
|
||||
// Create a new font
|
||||
Font scaledFont = new Font(watermark.Font, scalingFactor / 16 * (watermark.Font.Size * watermark.Scale));
|
||||
ImagePosition[] centerImagePositions = { ImagePosition.CenterLeft, ImagePosition.CenterRight, ImagePosition.Center };
|
||||
//processingContext.SetGraphicsOptions(new GraphicsOptions { AlphaCompositionMode = SixLabors.ImageSharp.PixelFormats.PixelAlphaCompositionMode.Clear});
|
||||
//If set, apply backround color
|
||||
if (watermark.BackroundColor != null)
|
||||
processingContext.BackgroundColor((Color)watermark.BackroundColor);
|
||||
|
||||
var textOptions = new RichTextOptions(scaledFont)
|
||||
{
|
||||
ColorFontSupport = ColorFontSupport.MicrosoftColrFormat,
|
||||
Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, watermark.Position),
|
||||
HorizontalAlignment = HorizontalAlignmentFromPosition(watermark.Position),
|
||||
VerticalAlignment = VerticalAlignment.Top,
|
||||
};
|
||||
|
||||
if (watermark.Pave)
|
||||
{
|
||||
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
||||
{
|
||||
textOptions.Origin = CalcWatermarkOrigin(imgSize.Width, imgSize.Height, scaledFont.Size, position);
|
||||
textOptions.HorizontalAlignment = HorizontalAlignmentFromPosition(position);
|
||||
processingContext.DrawText(textOptions, watermark.Text, watermark.Color);
|
||||
}
|
||||
return processingContext;
|
||||
}
|
||||
return processingContext
|
||||
.DrawText(textOptions, watermark.Text, watermark.Color);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies image watermark to target image with scaling and positioning.
|
||||
/// </summary>
|
||||
/// <param name="processingContext">Image processing context.</param>
|
||||
/// <param name="watermark">Image watermark configuration.</param>
|
||||
/// <param name="watermarkImage">Watermark image instance.</param>
|
||||
/// <param name="targetImage">Target image being processed.</param>
|
||||
/// <returns>Processing context with applied watermark.</returns>
|
||||
private IImageProcessingContext ApplyScalingWaterMarkImage(IImageProcessingContext processingContext, ImageWatermark watermark, Image watermarkImage, Image targetImage)
|
||||
{
|
||||
var scaleFactor = 1f;
|
||||
if (targetImage.Width > targetImage.Height)
|
||||
scaleFactor = (float)targetImage.Width / targetImage.Height;
|
||||
else
|
||||
scaleFactor = (float) targetImage.Height / targetImage.Width;
|
||||
|
||||
var wmPaddingX = (targetImage.Width - watermarkImage.Width) / 2;
|
||||
var wmPaddingY = (targetImage.Height - watermarkImage.Height) / 2;
|
||||
//scaleFactor = 1;
|
||||
var minWmPadding = 50;
|
||||
var scaledWmWidth = wmPaddingX > minWmPadding && wmPaddingY > minWmPadding
|
||||
? watermarkImage.Width * scaleFactor
|
||||
: watermarkImage.Width / scaleFactor;
|
||||
var scaledWmHeight = wmPaddingX > minWmPadding && wmPaddingY > minWmPadding
|
||||
? watermarkImage.Height * scaleFactor
|
||||
: watermarkImage.Height / scaleFactor;
|
||||
|
||||
//If set, apply backround color
|
||||
if (watermark.BackroundColor != null)
|
||||
processingContext.BackgroundColor((Color)watermark.BackroundColor);
|
||||
|
||||
watermarkImage.Mutate(x => x.Resize(new Size((int)scaledWmWidth, (int)scaledWmHeight)));
|
||||
var wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, watermark.Position);
|
||||
|
||||
if (watermark.Pave)
|
||||
{
|
||||
foreach (ImagePosition position in (ImagePosition[])Enum.GetValues(typeof(ImagePosition)))
|
||||
{
|
||||
wmPositionOrigin = CalcWatermarkOrigin(targetImage.Width, targetImage.Height, watermarkImage.Width, watermarkImage.Height, position);
|
||||
try
|
||||
{
|
||||
processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Opacity);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
}
|
||||
}
|
||||
return processingContext;
|
||||
}
|
||||
|
||||
return processingContext.DrawImage(watermarkImage, wmPositionOrigin, watermark.Opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Watermark.Net.src.WatermarkNet.Enums
|
||||
{
|
||||
public enum ImagePosition
|
||||
{
|
||||
TopLeft = 0,
|
||||
TopCenter = 1,
|
||||
TopRight = 2,
|
||||
CenterLeft = 3,
|
||||
Center = 4,
|
||||
CenterRight = 5,
|
||||
BottomLeft = 6,
|
||||
BottomCenter = 7,
|
||||
BottomRight = 8
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
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() { }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using SixLabors.ImageSharp;
|
||||
|
||||
namespace Watermark.Net.src.WatermarkNet.Types
|
||||
{
|
||||
internal class SourceImage
|
||||
{
|
||||
private string _path;
|
||||
private Image _image;
|
||||
|
||||
public Image Image => _image;
|
||||
public String Path => _path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
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()
|
||||
{
|
||||
_color = Color.White;
|
||||
_font = SystemFonts.CreateFont("Arial", 12);
|
||||
_padding = 10f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using SixLabors.ImageSharp;
|
||||
|
||||
namespace Watermark.Net.src.WatermarkNet.Types
|
||||
{
|
||||
public class WmarkedImage
|
||||
{
|
||||
public string Path { get; }
|
||||
public Image Image { get; }
|
||||
public WmarkedImage(Image image, string path)
|
||||
{
|
||||
this.Image = image;
|
||||
this.Path= path;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user