.NET生成水印更好的方法实例代码
前言
众所周知为了保护知识产权,防止资源被盗用,水印在博客、网店等场景中非常常见。
本文首先演示了基于system.drawing.image
做正常操作。然后基于direct2d/wic/directwrite,演示了一种全新、不同的“骚”操作。
方法1-system.drawing给图片加水印
system.drawing.image
原生属于gdi的一部分,是windows only,但随着nuget包system.drawing.common
的发布,现在system.drawing.image
已经支持linux:
install-package system.drawing.common -version 4.5.1
以下代码演示了如何从给图片加水印:
// 加水印 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); } }
效果如图(没有黄色剪头):
附:edi.wang做了一个nuget包,可以轻松地配置水印参数:
nuget:https://github.com/ediwang/edi.imagewatermark
文章:https://edi.wang/post/2018/10/12/add-watermark-to-uploaded-image-aspnet-core
方法2-direct2d/wic给图片加水印
direct2d源于windows 8/ie 10,安装ie 10之后,windows 7也能用。direct2d基于direct3d,很显然,是windows only的。
direct2d是windows下一代的2d渲染库,随着direct2d一起发布的,还有windows imaging component(简称wic)和directwrite。
相关说明和文档链接:
技术 | 说明 | 链接 |
---|---|---|
direct2d | 基于硬件加速的2d图形渲染 | go |
wic | 高性能图片编码、解码 | go |
directwrite | 基于硬件加速的文字渲染 | go |
如果您打开链接看了一眼,就不难看出,这些技术都是基于com的,但我们使用.net,不是吗?
好在我们有sharpdx
sharpdx对这些directx技术做了封装,在这个demo中,我们需要安装sharpdx.direct2d1和sharpdx.mathematics两个包:
install-package sharpdx.direct2d1 -version 4.2.0 install-package sharpdx.mathematics -version 4.2.0
以下代码演示了如何使用sharpdx.direct2d1给图片加水印:
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; } } }
调用方式:
file.writeallbytes(@"d:\_\demo2.png", addwatermark(file.openread(@"d:\_\watermarkdemo.png"), "水印在此").toarray());
效果也是一切正常:
有什么区别?
system.drawing只花了14行,direct2d却需要整整60行!复杂程度惊人!为什么要舍简单求复杂呢?
因为system.drawing没有硬件加速,而且生成的图片也没有反走样(anti-aliasing),这导致使用system.drawing
相比之下较慢,而且生成图片的效果稍差:
很明显可以看出,direct2d生成的图片更平滑。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。