当前位置: 首页 > news >正文

在C#中为图片添加数字水印的几种办法

最近在写个人项目时,有遇到需要将图片加上水印防止被盗取的需求。这里找了几种实现方式,可供有需要的朋友参考。

本身我不是搞算法这块的,所以这里只是找了一些实现,也没有继续深究下去。

以前在学校的时候从书上了解过可以将一些信息嵌入到图片中的技术,这次顺便也在网上找到了这种实现方式。

方式一,直接使用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到图片中,可以再次从图片中提取出来

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Xinstall全链路数据统计,助力推广者破解社交分享难题
  • 汇昌联信数字做拼多多运营怎么入行?
  • Python面试题:结合Python技术,如何使用TensorFlow进行深度学习模型训练与部署
  • 计算机网络知识点汇总第一章:概述
  • C语言实现希尔排序和堆排序
  • CDH清理磁盘空间完全攻略和完整实现自动化脚本(大数据清除日志)
  • 【Unity】3D功能开发入门系列(一)
  • 【课程系列07】某乎AI大模型全栈工程师-第7期
  • 手写chatGPT——fetch解析text/event-stream会话流并逐字回显到页面——js技能提升
  • 【C++BFS算法】2998. 使 X 和 Y 相等的最少操作次数
  • Redis作为缓存,如何与MySql的数据进行同步?
  • 7 postgresql 10版本 分区表使用场景、创建删除、注意事项
  • 熟悉简单测试面经
  • 代码随想录第二十一天|动态规划(5)
  • 3.2.2 最短路径 堆优化版Djkstra算法
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 2017-08-04 前端日报
  • cookie和session
  • ES6--对象的扩展
  • JS变量作用域
  • Js基础知识(四) - js运行原理与机制
  • Octave 入门
  • quasar-framework cnodejs社区
  • Spring核心 Bean的高级装配
  • Tornado学习笔记(1)
  • windows下如何用phpstorm同步测试服务器
  • 给Prometheus造假数据的方法
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 聊聊sentinel的DegradeSlot
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 一道面试题引发的“血案”
  • 一些css基础学习笔记
  • 移动端 h5开发相关内容总结(三)
  • 原生js练习题---第五课
  • 在weex里面使用chart图表
  • 转载:[译] 内容加速黑科技趣谈
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​云纳万物 · 数皆有言|2021 七牛云战略发布会启幕,邀您赴约
  • # Maven错误Error executing Maven
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $$$$GB2312-80区位编码表$$$$
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (27)4.8 习题课
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (C)一些题4
  • (ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Oracle)SQL优化技巧(一):分页查询
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (二十四)Flask之flask-session组件
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (九)c52学习之旅-定时器