Watermark better way to generate .NET
In order to protect intellectual property from unauthorized use of resources, watermarks in blog, shop and other scenes are very common.
This paper demonstrates on System.Drawing.Image
doing normal operation. Then, based on Direct2D
/ WIC
/ DirectWrite
, demonstrate a new, different " show " operation.
Method 1 - System.Drawing
to add a watermark picture
System.Drawing.Image
Native belong to GDI
a part of, is Windows Only, but with NuGet package System.Drawing.Common release, now System.Drawing.Image
has support for linux
:
Install-Package System.Drawing.Common -Version 4.5.1
The following code demonstrates how to add a watermark to the picture from:
// 加水印
var watermarkedStream = new MemoryStream();
using (var img = Image.FromStream(File.OpenRead(@"D:\_\WatermarkDemo.png")))
{
using (var graphic = Graphics.FromImage(img))
{
var font = new Font("微软雅黑", 30, FontStyle.Bold, GraphicsUnit.Pixel);
var color = Color.FromArgb(128, 255, 255, 255);
var brush = new SolidBrush(color);
var point = new Point(img.Width - 130, img.Height - 50);
graphic.DrawString("水印在此", font, brush, point);
img.Save(watermarkedStream, ImageFormat.Png);
}
}
FIG effect (no yellow shear head):
Attached: Edi.Wang made a NuGet package, you can easily configure watermark parameters:
- NuGet:https://github.com/EdiWang/Edi.ImageWatermark
- Article: https: //edi.wang/post/2018/10/12/add-watermark-to-uploaded-image-aspnet-core
Method 2 Direct2D
/ WIC
to images watermarked
Direct2D
From Windows 8
/ IE 10
to install IE 10
later, Windows 7
also can be used. Direct2D
Based Direct3D
, apparently, it is a Windows Only.
Direct2D
It is Windows
the next generation of 2D rendering library, as Direct2D
published together, as well as Windows Imaging Component
(for short WIC
) and DirectWrite
.
Instructions and document links:
technology | Explanation | link |
---|---|---|
Direct2D |
Hardware accelerated 2D graphics rendering | Go |
WIC |
High-performance picture encoding, decoding | Go |
DirectWrite |
Hardware-accelerated text rendering | Go |
If you open the link looked at, it is easy to see that these techniques are based on COM
, but we use .NET
, is not it?
Fortunately, we haveSharpDX
SharpDX
These DirectX
techniques do packaging, in this Demo, we need to be installed SharpDX.Direct2D1
and SharpDX.Mathematics
two packages:
Install-Package SharpDX.Direct2D1 -Version 4.2.0
Install-Package SharpDX.Mathematics -Version 4.2.0
The following code demonstrates how SharpDX.Direct2D1
to add a watermark picture:
using D2D = SharpDX.Direct2D1;
using DWrite = SharpDX.DirectWrite;
using SharpDX;
using SharpDX.IO;
using WIC = SharpDX.WIC;
MemoryStream AddWatermark(Stream fileName, string watermarkText)
{
using (var wic = new WIC.ImagingFactory2())
using (var d2d = new D2D.Factory())
using (var image = CreateWicImage(wic, fileName))
using (var wicBitmap = new WIC.Bitmap(wic, image.Size.Width, image.Size.Height, WIC.PixelFormat.Format32bppPBGRA, WIC.BitmapCreateCacheOption.CacheOnDemand))
using (var target = new D2D.WicRenderTarget(d2d, wicBitmap, new D2D.RenderTargetProperties()))
using (var bmpPicture = D2D.Bitmap.FromWicBitmap(target, image))
using (var dwriteFactory = new SharpDX.DirectWrite.Factory())
using (var brush = new D2D.SolidColorBrush(target, new Color(0xff, 0xff, 0xff, 0x7f)))
{
target.BeginDraw();
{
target.DrawBitmap(bmpPicture, new RectangleF(0, 0, target.Size.Width, target.Size.Height), 1.0f, D2D.BitmapInterpolationMode.Linear);
target.DrawRectangle(new RectangleF(0, 0, target.Size.Width, target.Size.Height), brush);
var textFormat = new DWrite.TextFormat(dwriteFactory, "微软雅黑", DWrite.FontWeight.Bold, DWrite.FontStyle.Normal, 30.0f);
target.DrawText(watermarkText, textFormat, new RectangleF(target.Size.Width - 130, target.Size.Height - 50, int.MaxValue, int.MaxValue), brush);
}
target.EndDraw();
var ms = new MemoryStream();
SaveD2DBitmap(wic, wicBitmap, ms);
return ms;
}
}
void SaveD2DBitmap(WIC.ImagingFactory wicFactory, WIC.Bitmap wicBitmap, Stream outputStream)
{
using (var encoder = new WIC.BitmapEncoder(wicFactory, WIC.ContainerFormatGuids.Png))
{
encoder.Initialize(outputStream);
using (var frame = new WIC.BitmapFrameEncode(encoder))
{
frame.Initialize();
frame.SetSize(wicBitmap.Size.Width, wicBitmap.Size.Height);
var pixelFormat = wicBitmap.PixelFormat;
frame.SetPixelFormat(ref pixelFormat);
frame.WriteSource(wicBitmap);
frame.Commit();
encoder.Commit();
}
}
}
WIC.FormatConverter CreateWicImage(WIC.ImagingFactory wicFactory, Stream stream)
{
using (var decoder = new WIC.PngBitmapDecoder(wicFactory))
{
var decodeStream = new WIC.WICStream(wicFactory, stream);
decoder.Initialize(decodeStream, WIC.DecodeOptions.CacheOnLoad);
using (var decodeFrame = decoder.GetFrame(0))
{
var converter = new WIC.FormatConverter(wicFactory);
converter.Initialize(decodeFrame, WIC.PixelFormat.Format32bppPBGRA);
return converter;
}
}
}
Invocation:
File.WriteAllBytes(@"D:\_\Demo2.png", AddWatermark(File.OpenRead(@"D:\_\WatermarkDemo.png"), "水印在此").ToArray());
The effect is as usual:
What's the difference?
System.Drawing
It took only 14 lines, Direct2D
it takes a full 60 rows! The complexity of amazing! Why do you want to round it simple Complicated?
Because System.Drawing
there is no hardware acceleration, and the resulting picture is also no anti-aliasing ( Anti-aliasing
), which leads to the use of System.Drawing
contrast slower, less effective and the resulting picture:
It is obvious that the Direct2D
resulting image is smoother.
Author: Zhou Jie
Source: https: //www.cnblogs.com/sdflysha
This article uses Creative Commons Attribution - NonCommercial - ShareAlike 2.5 license agreement in China to license, welcome to reprint, but without the author's consent must keep this paragraph statement, and given the original connection in the apparent position of the article page.