基于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#实现封装

-
  • 1970年01月01日 08:00

【MATLAB】基于DCT变换的数字水印

一年前的媒体信号处理的课程的project,现在翻出来打算用python写一遍然而发现自己对这段代码毫无记忆 可能写的时候活在梦里 (:△」∠) 翻出来回味一下……注释里面写得很详尽了。 其实因...
  • Dango_miracle
  • Dango_miracle
  • 2017-10-27 17:25:35
  • 1452

基于DCT数字水印算法的Matlab实现源代码

  • 2013年04月12日 09:10
  • 14KB
  • 下载

DCT数字水印实现

  • 2015年06月05日 16:45
  • 555B
  • 下载

基于DWT的数字水印代码

  • 2013年06月04日 11:05
  • 275KB
  • 下载

基于MATLAB的数字水印技术研究

摘要:数字水印技术作为数字媒体版权保护的有效办法,近年来在国内外引起了人们极大的兴趣。但是由于数字水印技术涉及到的知识面比较广,即使是专业人员有时也感到力不从心,那么如何选择一种有效的编程工具便成为一...
  • jiangxinyu
  • jiangxinyu
  • 2006-12-15 17:33:00
  • 10606

一个基于dct变换的数字水印算法的源程序.rar

  • 2012年05月24日 23:13
  • 187KB
  • 下载

Java数字水印技术,包含所有主流数字水印技术的Java实现

  • 2009年08月28日 20:30
  • 7.71MB
  • 下载

基于的DCT水印算法实现

上学期帮同校本科的同学做了毕业设计的实验部分,用MATLAB实现DCT水印算法,并且包含了攻击测试。先讲一个大体概念,然后放出具体代码。一、DCTDCT(离散余弦变换),这里只以二维DCT为例。 信...
  • zxc024000
  • zxc024000
  • 2015-10-26 20:38:11
  • 8473

基于dct变换的数字水印嵌入算法

  • 2011年07月02日 15:23
  • 51KB
  • 下载
收藏助手
不良信息举报
您举报文章:基于C#实现数字水印工具
举报原因:
原因补充:

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