Skip to content

Commit 78d802a

Browse files
committed
Added watermark filter
1 parent 497d22d commit 78d802a

File tree

15 files changed

+181
-72
lines changed

15 files changed

+181
-72
lines changed

src/ImageWizard.Client/Builder/ImageFilterExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ public static Image Invert(this Image image)
161161
return image;
162162
}
163163

164+
public static Image Watermark(this Image image)
165+
{
166+
image.Filter($"watermark()");
167+
168+
return image;
169+
}
170+
164171
public static Image Saturate(this Image image, double value)
165172
{
166173
image.Filter($"saturate({value.ToUrlString()})");
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/ImageWizard
3+
// MIT License
4+
5+
using ImageWizard.Attributes;
6+
using Microsoft.Extensions.Options;
7+
using SixLabors.ImageSharp;
8+
using SixLabors.ImageSharp.Processing;
9+
10+
namespace ImageWizard.ImageSharp.Filters;
11+
12+
public class WatermarkFilter : ImageSharpFilter
13+
{
14+
public WatermarkFilter(IOptions<WatermarkOptions> options)
15+
{
16+
Options = options.Value;
17+
}
18+
19+
/// <summary>
20+
/// Options
21+
/// </summary>
22+
private WatermarkOptions Options { get; }
23+
24+
[Filter]
25+
public void Watermark(WatermarkLocation location)
26+
{
27+
if (string.IsNullOrEmpty(Options.Image))
28+
{
29+
throw new Exception("Watermark image is missing.");
30+
}
31+
32+
using Image watermark = Image.Load(Options.Image);
33+
34+
Point point = location switch
35+
{
36+
WatermarkLocation.TopLeft => new Point(Options.Margin, Options.Margin),
37+
WatermarkLocation.TopRight => new Point(Context.Image.Width - watermark.Width - Options.Margin, Options.Margin),
38+
WatermarkLocation.BottomLeft => new Point(Options.Margin, Context.Image.Height - watermark.Height - Options.Margin),
39+
WatermarkLocation.BottomRight => new Point(Context.Image.Width - watermark.Width - Options.Margin, Context.Image.Height - watermark.Height - Options.Margin),
40+
_ => throw new Exception($"Unknown watermark location: {location}")
41+
};
42+
43+
Context.Image.Mutate(m => m.DrawImage(watermark, point, Options.Opacity));
44+
}
45+
46+
[Filter]
47+
public void Watermark()
48+
{
49+
Watermark(Options.Location);
50+
}
51+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/ImageWizard
3+
// MIT License
4+
5+
using ImageWizard.Attributes;
6+
using Microsoft.Extensions.Options;
7+
using SixLabors.ImageSharp;
8+
using SixLabors.ImageSharp.Processing;
9+
10+
namespace ImageWizard.ImageSharp.Filters;
11+
12+
public enum WatermarkLocation
13+
{
14+
TopLeft,
15+
TopRight,
16+
BottomLeft,
17+
BottomRight
18+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) usercode
2+
// https://github.com/usercode/ImageWizard
3+
// MIT License
4+
5+
namespace ImageWizard.ImageSharp.Filters;
6+
7+
public class WatermarkOptions
8+
{
9+
public WatermarkOptions()
10+
{
11+
Margin = 10;
12+
Opacity = 0.5f;
13+
Location = WatermarkLocation.BottomRight;
14+
}
15+
16+
/// <summary>
17+
/// Margin
18+
/// </summary>
19+
public int Margin { get; set; }
20+
21+
/// <summary>
22+
/// Path to the watermark image
23+
/// </summary>
24+
public string? Image { get; set; }
25+
26+
/// <summary>
27+
/// Opacity
28+
/// </summary>
29+
public float Opacity { get; set; }
30+
31+
/// <summary>
32+
/// Location
33+
/// </summary>
34+
public WatermarkLocation Location { get; set; }
35+
}

src/ImageWizard.ImageSharp/ImageWizardBuilderExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public static IImageWizardBuilder AddImageSharp(this IImageWizardBuilder builder
3838
pipelineBuilder.WithFilter<MetadataFilter>();
3939
pipelineBuilder.WithFilter<ImageFormatFilter>();
4040
pipelineBuilder.WithFilter<TextFilter>();
41+
pipelineBuilder.WithFilter<WatermarkFilter>();
4142

4243
pipelineBuilder.WithMimeTypes(new[] { MimeTypes.WebP, MimeTypes.Jpeg, MimeTypes.Png, MimeTypes.Gif, MimeTypes.Tga, MimeTypes.Bmp });
4344

-698 KB
Binary file not shown.

src/ImageWizard.TestApp/FileStorage/img/dot-net-core.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.
-447 KB
Binary file not shown.
-603 KB
Binary file not shown.

src/ImageWizard.TestApp/Pages/Index.cshtml

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,7 @@
3939
<p>@@Url.ImageWizard().Screenshot("https://github.com").BuildUrl()</p>
4040
<p>@Url.ImageWizard().Screenshot("https://github.com").BuildUrl()</p>
4141

42-
<img src="@Url.ImageWizard().Screenshot("https://github.com").BuildUrl()" />
43-
44-
<h2>OpenStreetMap</h2>
45-
<p>Use as relay to openstreetmap server. </p>
46-
47-
@* <img src="@Url.ImageWizard().OpenStreetMap(1,1,1).BuildUrl()" />*@
48-
49-
<div tabindex="650" id="map" style="height:600px"></div>
50-
51-
<link rel="stylesheet" href="~/lib/leaflet/leaflet.css" />
52-
<script src="~/lib/leaflet/leaflet.js" asp-append-version="true" ></script>
53-
<script>
54-
// Create the map
55-
var map = L.map('map').setView([45, 10], 4);
56-
57-
// Set up the OSM layer
58-
L.tileLayer('https://' + window.location.host + '/image/osm/{z}/{x}/{y}.png').addTo(map);
59-
</script>
42+
<img src="@Url.ImageWizard().Screenshot("https://github.com").BuildUrl()" />
6043

6144
<h2>SVG transforming</h2>
6245
<p>@@Url.ImageWizard().FetchLocalFile("img/dot-net-core.svg").BuildUrl()</p>
@@ -170,15 +153,18 @@
170153
</div>
171154
</div>
172155

156+
<h2>Watermark</h2>
157+
<p>@@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg", 4).AsImage().Watermark().BuildUrl()</p>
158+
<p>@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg", 4).AsImage().Watermark().BuildUrl()</p>
159+
160+
<img src="@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg", 4).AsImage().Resize(400, 400).Watermark().BuildUrl()" />
161+
173162
<h2>Draw text</h2>
174163
<p>@@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg", 4).AsImage().Resize(400, 400).DrawText("bat-eared-fox", 65, 0.3, 0.1, false).BuildUrl()</p>
175164
<p>@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg", 4).AsImage().Resize(400, 400).DrawText("bat-eared-fox", 65, 0.3, 0.1, false).BuildUrl()</p>
176165

177-
<div class="row">
178-
<div class="col-lg-4">
179-
<img src="@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg").AsImage().Resize(400,400).DrawText("bat eared fox", 65, 0.3, 0.1, false).BuildUrl()" />
180-
</div>
181-
</div>
166+
<img src="@Url.ImageWizard().FetchLocalFile("img/bat-eared-fox.jpg").AsImage().Resize(400,400).DrawText("bat eared fox", 65, 0.3, 0.1, false).BuildUrl()" />
167+
182168

183169
@* <h2>Resize WebP image with SkiaSharp</h2>
184170
<div class="row">
@@ -247,17 +233,17 @@
247233
<p>@@Url.ImageWizard().File("img/meerkat.jpg").AsImage().Resize(400,400).BuildUrl()</p>
248234
<p>@Url.ImageWizard().File("img/meerkat.jpg").AsImage().Resize(400, 400).BuildUrl()</p>
249235

250-
@*<div class="row">
236+
<div class="row">
251237
<div class="col-lg-4">
252-
<img src="@Url.ImageWizard().File("/img/meerkat.jpg").AsImage().Resize(400,400).BuildUrl()" />
238+
<img src="@Url.ImageWizard().File("img/meerkat.jpg").AsImage().Resize(400,400).BuildUrl()" />
253239
</div>
254240
<div class="col-lg-4">
255-
<img src="@Url.ImageWizard().File("/img/meerkat.jpg").AsImage().Resize(400,400).Grayscale().BuildUrl()" />
241+
<img src="@Url.ImageWizard().File("img/meerkat.jpg").AsImage().Resize(400,400).Grayscale().BuildUrl()" />
256242
</div>
257243
<div class="col-lg-4">
258-
<img src="@Url.ImageWizard().File("/img/meerkat.jpg").AsImage().Resize(400,400).Blur().BuildUrl()" />
244+
<img src="@Url.ImageWizard().File("img/meerkat.jpg").AsImage().Resize(400,400).Blur().BuildUrl()" />
259245
</div>
260-
</div>*@
246+
</div>
261247

262248
<h2>Fetch youtube thumbnail</h2>
263249

@@ -319,4 +305,19 @@
319305
<p>@Url.ImageWizard().FetchLocalFile("/pdf/earth.pdf").AsPdf().PageToImage(0).BuildUrl()</p>
320306

321307
<img src="@Url.ImageWizard().FetchLocalFile("/pdf/earth.pdf").AsPdf().PageToImage(0).BuildUrl()" />
308+
309+
<h2>OpenStreetMap</h2>
310+
<p>Use as relay to openstreetmap server. </p>
311+
312+
<div tabindex="650" id="map" style="height:600px"></div>
313+
314+
<link rel="stylesheet" href="~/lib/leaflet/leaflet.css" />
315+
<script src="~/lib/leaflet/leaflet.js" asp-append-version="true" ></script>
316+
<script>
317+
// Create the map
318+
var map = L.map('map').setView([45, 10], 4);
319+
320+
// Set up the OSM layer
321+
L.tileLayer('https://' + window.location.host + '/image/osm/{z}/{x}/{y}.png').addTo(map);
322+
</script>
322323
</div>

0 commit comments

Comments
 (0)