基于C#实现数字水印工具

转载 2007年10月12日 09:07:00
基于C#实现数字水印工具
摘要
基于C#提供的Image类,实现数字水印比较容易;这里强调的是如何做可release的一个工具。
照片添加
利用C#的FolderBrowserDialog类,可以方便地的读取图像文件。本文是基于目录添加照片,所以需要进行目录遍历。如果打开的是目录,还需要打开子目录读取照片;在本文实现中,只读取JPG文件,并且在添加前试着读一下,避免一些图片不能读取,影响后续操作的有效性。
另外,从FolderBrowserDialog类得到路径后,不要忘记读取该目录下的文件,这是一个容易忽略的小问题,即get_file(fbdlg.SelectedPath)后再调用get_dir(fbdlg.SelectedPath)。

private void get_dir(string parent)
        {
            DirectoryInfo di = new DirectoryInfo(parent);
            foreach (DirectoryInfo subdir in di.GetDirectories())
            {
                get_file(subdir.FullName);
            }
        }
        private void get_file(string parent)
        {
            DirectoryInfo di = new DirectoryInfo(parent);
            foreach (FileInfo fi in di.GetFiles())
            {
                if (fi.Extension.ToUpper() == ".JPG")
                {
                    try
                    {
                        Image test = Image.FromFile(fi.FullName);
                        if (test != null)
                        {
                            insertPhoto(fi);
                            test.Dispose();
                        }
                    }
                    catch (OutOfMemoryException ome)
                    {
                        MessageBox.Show(fi.FullName + " can not be added into album" + Environment.NewLine + "reason[" + ome.Message + "]");
                    }
                    catch (FileNotFoundException fnfe)
                    {
                        MessageBox.Show(fi.FullName + " can not be added into album" + Environment.NewLine + "reason[" + fnfe.Message + "]");
                    }
                    catch (ExternalException)
                    {
                        continue;
                    }
                }
            }              
       }
接下来的问题是:读入的照片,如何显示?考虑到本工具不是图片处理,需求Scope比较容易确定;缩略图是个最佳选择。想到缩略图,就想到了利用ListView来显示添加的图片:LargeImageList刚好满足要求;另外,ListViewItem的CheckBox正好用来选定图片。

this.listView1.LargeImageList = il;
                for (int i = 0; i < il.Images.Count; i++)
                {
                    ListViewItem lvi = new ListViewItem();
                    lvi.Name = new FileInfo(img_files[i]).Name;
                    lvi.ImageIndex = i;                    
                    this.listView1.Items.Add(lvi);
                }
图片选取
ListView的ListViewItem有个名为Checked的属性,只要改变这个属性,就能全部选择和全部取消选择。

private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in this.listView1.Items)
            {
                if (!lvi.Checked)
                {
                    lvi.Checked = true;
                }
            }
        }
 
        private void unselectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in this.listView1.Items)
            {
                if (lvi.Checked)
                {
                    lvi.Checked = false;
                }
            }
        }
水印定制
字符水印可以改变字体的大小、颜色、字体名和水印内容;这里提供定制模态对话框。在该对话框中有个RichTextBox来显示定制的实际效果;当然会使用FontDialog类。

FontDialog fdlg = new FontDialog();
            fdlg.Font = m_font;
            fdlg.ShowColor = true;
           fdlg.ShowEffects = true;
            if (DialogResult.OK == fdlg.ShowDialog())
            {
                this.richTextBox1.Font = fdlg.Font;               
                this.richTextBox1.ForeColor = fdlg.Color;               
            }
            fdlg.Dispose();
当对话框按确定按钮时,需要将定制信息保存下来,并持久化;本文使用注册表(关于注册表操作请参见《基于C#操作注册表》一文)。

Tips:关于模态对话框的实现。
在C#中,只有Form类;通过调用ShowDialog时指定parent,来实现模态。另外,还需要在对话框的确定和取消按钮的DialogResult属性,指定相应的返回值。
 
水印添加
添加水印的过程有点类似photoshop的图层:
1) 一个同样大小的Bitmap;new
2)复制图片属性,如分辨率信息,日期等;
3)先将该图层涂白;
4)再把原图画在上面;
5)然后把文字写在上面;
6)保存。

private void watermarkphoto(string filename, Image img)
        {           
            Bitmap b = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppRgb);
            b.SetResolution(img.HorizontalResolution, img.VerticalResolution);
            foreach (PropertyItem item in img.PropertyItems)
            {
                b.SetPropertyItem(item);
            }
            Graphics g = Graphics.FromImage(b);
            g.Clear(Color.White);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            g.DrawImage(img, 0, 0, img.Width, img.Height);
            SolidBrush brush = new SolidBrush(m_default_color);           
            StringFormat format = new StringFormat(StringFormatFlags.NoClip);
            format.LineAlignment = StringAlignment.Near;
            format.Alignment = StringAlignment.Near;        
            SizeF stringSize = g.MeasureString(m_defalut_watermark, m_default_font);
            g.DrawString(m_defalut_watermark, m_default_font, brush, new PointF((img.Width - stringSize.Width) / 2, img.Height *2 /3), format);
            try
            {
                b.Save(filename, ImageFormat.Jpeg);
            }
            catch (ExternalException ee)
            {
                MessageBox.Show("fail to handle " + filename + " because " + ee.Message);
            }
          b.Dispose();
            brush.Dispose();
            g.Dispose();           
        }
当然,改变字体后要计算一下水印宽度。
 

SizeF stringSize = g.MeasureString(m_defalut_watermark, m_default_font);
结束语
基于上述思想,实现的数字水印工具已经发布给几个朋友使用,反映良好。拥有自己的水印工具后,展示照片就不担心侵权了。 

C#软件开发实例.私人订制自己的屏幕截图工具(四)基本截图功能实现

实现原理:基本截图的功能主要靠响应主窗体的鼠标按下、鼠标移动、鼠标抬起几个事件的功能来实现的。截取的图片区域使用“Label”组件来显示,需要重新实现“Label”组件的“Paint”方法。左键单击开...
  • testcs_dn
  • testcs_dn
  • 2014年04月10日 13:11
  • 9875

C#软件开发实例.私人订制自己的屏幕截图工具(一)功能概览

概述 开发该软件的原因主要是想订制实现自己想要的功能,比如:自动保存,气泡提示框类型的标注功(主要用于功能说明文档的写作)能。 托盘图标及菜单 添加托盘图标,是因为有些功能还是需要使用菜单呼出...
  • testcs_dn
  • testcs_dn
  • 2014年04月08日 11:50
  • 8781

C# 自己实现的一套ORM程序附带实体生成工具

程序下载地址:C# 自已实现ORM程序下载 实体生成工具下载:实体生成工具下载...
  • zhang116868
  • zhang116868
  • 2015年11月13日 18:31
  • 2515

C#常用工具类

using System; using System.IO; using System.Text.RegularExpressions; using System.Windows.Browser; ...
  • cyj380236628
  • cyj380236628
  • 2015年11月13日 22:54
  • 1606

c#实现画图功能

1             //描绘曲线              //创建曲线中的点                  Point point1 = new Point(68, 420)...
  • gny315
  • gny315
  • 2015年04月01日 20:31
  • 3629

C#常用工具类——Excel操作类

// 常用工具类——Excel操作类 ///  ------------------------------------------------ ///  CreateConnecti...
  • wuyuander
  • wuyuander
  • 2017年06月06日 11:09
  • 530

C# HTTP工具类

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net...
  • qq183518918
  • qq183518918
  • 2013年12月20日 10:25
  • 1604

【C#工具类】导出Excel

从DataTable中导出Excel: public static void ExportToExcelByDataTableAndFileName(DataTable dt, string File...
  • f627422467
  • f627422467
  • 2016年11月07日 10:40
  • 301

关于C#使用工具类解析JSON数据以及将类JSON化

项目中做的开发,记录下。 C#处理JSON数据还是相当方便的,System.Runtime.Serialization.Json提供了非常好用的相关方法。 首先,我们需要弄清楚需要处理的JSON的...
  • carlblack1987
  • carlblack1987
  • 2017年03月24日 16:56
  • 160

C#版的抓包软件

NetAnalyzer实现结构 在上一篇中介绍一点VC++开发环境的配置,与基本的运行方式。因为NetAnalyzer使用的C#作为开发语言,所以在此主要介绍一些在C#环境下的开发环境的配置,与...
  • qq_36095086
  • qq_36095086
  • 2017年04月20日 18:53
  • 464
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于C#实现数字水印工具
举报原因:
原因补充:

(最多只允许输入30个字)