最近在写个人项目时,有遇到需要将图片加上水印防止被盗取的需求。这里找了几种实现方式,可供有需要的朋友参考。
本身我不是搞算法这块的,所以这里只是找了一些实现,也没有继续深究下去。
以前在学校的时候从书上了解过可以将一些信息嵌入到图片中的技术,这次顺便也在网上找到了这种实现方式。
方式一,直接使用GDI+绘制水印到图片上
这种方式的话存在几个问题
1、水印很容易被清除,用ps的内容识别一下就干掉了
2、水印的文字大小不好控制(理论是可以根据图片的大小动态计算字符的大小的,以前见过这种实现,但这里我也没去仔细找实现了,就大概写了个根据图片大小调整字符大小的逻辑。)
实现逻辑如下:
1 public static void DrawWatermark(string imageFilePath,string watermark) 2 { 3 using (MemoryStream ms = new MemoryStream(System.IO.File.ReadAllBytes(imageFilePath))) 4 { 5 Bitmap bitmap = (Bitmap)Image.FromStream(ms); 6 7 using (Graphics graphics = Graphics.FromImage(bitmap)) 8 { 9 var size = (float)(bitmap.Height * 0.02); 10 if (size < 10) 11 size = 10f; 12 using (Font arialFont = new Font("Arial", size, GraphicsUnit.Pixel)) 13 { 14 var location = new Point(0, 0); 15 graphics.DrawString(watermark, arialFont, new SolidBrush(Color.FromArgb(120, Color.Silver)), location); 16 } 17 } 18 19 bitmap.Save(imageFilePath); 20 } 21 }
绘制出来大概效果如下:
方式二、将图片信息嵌入到图片中
这是我在github上找到一种实现方式,项目地址:GitHub - mchall/HiddenWatermark: Embeds a hidden watermark in an image using a blind DWT-DCT approach
项目描述:
使用盲DWT-DCT方法在图像中嵌入隐藏水印。与隐写方法不同,这种隐藏水印能够抵抗各种形式的攻击。仅限于黑白32x32水印图像。
项目里有示例,可以根据示例进行调用。
使用这种方法,可以将一个32x32的黑白图像嵌入到图片中。
经过我实际 测试,发现如果图片太小,是不支持这种嵌入方式 的。个人推断应该是如果图片太小,还未达到写入32x32图片的空间大小。具体最小支持到什么尺寸的图片,我也没有仔细去计算了。
效果如下:
我这里弄了一张写了zti三个字的灰度图,然后嵌入到图片中去。
+
嵌入 后,图片看起来跟原始图像没有区别,但是能再次把嵌入的图片提取出来
方式三、将文字信息嵌入到图片中
这是我在CodeProject上找到的一种实现方式。可以在下面的链接中下载到实现的源码和示例程序,直接参考集成即可。
项目地址:Steganography: Simple Implementation in C# - CodeProject
使用这种方式,可以将文字嵌入到图片中,然后再次提取出来。
注意:注意:不要以有损格式(如 JPEG)保存结果图像;推荐是保存为PNG。
效果如下:
我这里嵌入了HelloWorld到图片中,可以再次从图片中提取出来