我记录网站综合系统 -- 技术原理解析[2:C# 水印和验证码的制作]

标签: 记录 网站 系统 | 发表时间:2011-06-13 09:16 | 作者:magicDict brett80
出处:http://www.cnblogs.com/

代码位置:wojilu\Drawing\Watermark.cs

水印的定义:水印一般是指在图片上的一些版权信息文字,或者为了某种目的而对原始图片上附加一些图形或者文字。

水印的基本制作方法就是使用GDI+的方法在图片的制定位置上绘制文字或者图片。

说到GDI+,一般用于Winform对于GUI的绘制,例如文本编辑器的制作,就是使用GDI函数绘制文字在窗体表面。其实GDI不仅可以绘制窗体,它可以绘制一切的Drawable的表面。

我记录的水印制作就是利用GDI函数,进行原图和水印图片的合并,或者在原图上绘制文字。

 

关键GDI函数:(System.Drawing.Graphics 类的方法)

DrawImage  绘制图片

DrawString  绘制文字

这两个函数有大量的重载,具体请查阅MSDN。


 水印图片:

    水印图片一般是使用纯绿或者纯蓝背景色的图片,就和拍摄电影一样,在拍摄的时候,演员在绿色背景里面演戏,在后期制作的时候,绿色的背景都会被透明色所取代掉。在C#里面,我们使用SetRemapTable这个图像特性来完成这个工作。它的作用是让图片上面某个颜色被另一种颜色所替换掉。OldColor 就是要被取代掉的颜色,NewColor则是新的颜色。5-10行则是完成这样的操作。

     接下来就是将图片的所有点的透明度下降为原来的30%。这里将使用ColorMatrix来做。矩阵,在很多地方被大量使用,特别是变换的地方,例如图片的拉伸,缩放等等,都是利用了矩阵乘法的快速运算。这里也使用了矩阵来进行全像素的高速变换。仔细观察12行的矩阵的对角线上的数字:1,1,1,0.3,1 这些是倍数运算因子。对应则RGBAW的变换倍数。RGB不变,透明度为原来的0.3倍。W也不变。通过这种方法,就将图片的透明度降低了。

    这些颜色变换,在Draw方法执行时候,才进行变换。

 1         private static ImageAttributes getImageAttributes() {
 2 
 3             ImageAttributes imgAttr = new ImageAttributes();
 4 
 5             ColorMap colorMap = new ColorMap();
 6             colorMap.OldColor = Color.FromArgb( 25502550 );
 7             colorMap.NewColor = Color.FromArgb( 0000 );
 8             ColorMap[] remapTable = { colorMap };
 9 
10             imgAttr.SetRemapTable( remapTable, ColorAdjustType.Bitmap );
11 
12             float[][] colorMatrixElements = { 
13                new float[] {1.0f,  0.0f,  0.0f,  0.0f0.0f},
14                new float[] {0.0f,  1.0f,  0.0f,  0.0f0.0f},
15                new float[] {0.0f,  0.0f,  1.0f,  0.0f0.0f},
16                new float[] {0.0f,  0.0f,  0.0f,  0.3f0.0f},
17                new float[] {0.0f,  0.0f,  0.0f,  0.0f1.0f}
18             };
19 
20             ColorMatrix wmColorMatrix = new ColorMatrix( colorMatrixElements );
21             imgAttr.SetColorMatrix( wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap );
22 
23             return imgAttr;
24         }

 

水印绘制的地方,也没有必要贴全部代码了

 

1             ImageAttributes imgAttr = getImageAttributes();
2             Rectangle rect = getPicPoint( src, wm, wp );
3 
4             g.DrawImage( wm, rect, 00, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr );

 

第一行,取得刚才那个变换规则

第二行,取得绘制水印的矩形:我们可以指定水印的位置,比如左上角,右下角等等。通过位置的指定,获得不同的绘制区域的矩形。不过,getPicPoint 这个方法名称不好,让人误以为返回一个Point对象,其实是一个矩阵对象。建议换为getPicPosition或者getPicRect

第三行就是绘制,在指定地方,使用指定颜色变换,绘制指定图片。

 

绘制水印文字就相当简单了,使用一个透明的笔刷在图片上绘制水印即可。

 

  FontAndSize fs = FontAndSize.GetValue( g, words, "arial", fontSize, src.Width );
  PointF p 
= getTextPoint( src, fs.size, wp );
  StringFormat sf 
= getStringFormat();

  drawText( g, words, fs.font, p, sf );

 

 

当然,这里我记录用了两种颜色绘制出文字,达到具有阴影效果文字特效。可以看出作者非常用心在开发我记录啊。。。。

1         private static void drawText( Graphics g, String wmText, Font font, PointF p, StringFormat format ) {
2 
3             SolidBrush brush = new SolidBrush( Color.FromArgb( 153255255255 ) );
4             g.DrawString( wmText, font, brush, p, format );
5 
6             SolidBrush brush2 = new SolidBrush( Color.FromArgb( 153000 ) );
7             g.DrawString( wmText, font, brush2, new PointF( p.X + 1, p.Y + 1 ), format );
8         }

 

当然,代码里面的注释太少了,可能是非核心类,所以没有注释。当然,我们会在以后逐渐把注释补足的。作为一个服务大众的项目,注释是不能缺少的,让每个人看得懂的代码,是我们的目标。

验证码的制作在 wojilu\Drawing\ValidationCode.cs

验证码的制作可以分为3个步骤

1.绘制一个带有噪点的背景

2.绘制验证码

3.最上层再绘制一些噪点

 

 1         public Image CreateImage( String code, int width, int height, String fontFamily ) {
 2 
 3             Bitmap bm = new Bitmap( width, height );
 4 
 5             using (Graphics g = Graphics.FromImage( bm )) {
 6 
 7                 g.SmoothingMode = SmoothingMode.AntiAlias;
 8 
 9                 HatchBrush brush = new HatchBrush( HatchStyle.SmallConfetti, Color.LightGray, Color.White );
10                 Rectangle rect = new Rectangle( 00, width, height );
11                 g.FillRectangle( brush, rect );
12 
13                 int fontsize = rect.Height + 1;
14                 FontAndSize size = FontAndSize.GetValue( g, code, fontFamily, fontsize, bm.Width );
15 
16                 GraphicsPath gpath = getGraphicsPath( code, size.font, rect );
17 
18                 Color brushColor = ColorTranslator.FromHtml( "#000000" );
19                 brush = new HatchBrush( HatchStyle.Divot, brushColor, Color.DarkGray );
20                 g.FillPath( brush, gpath );
21 
22                 addRandomNoise( g, rect );
23 
24             }
25             return bm;
26         }
27 
28         private void addRandomNoise( Graphics g, Rectangle rect ) {
29 
30             HatchBrush brush = new HatchBrush( HatchStyle.Weave, Color.LightGray, Color.White );
31 
32             int m = Math.Max( rect.Width, rect.Height );
33             for (int i = 0; i < (int)(rect.Width * rect.Height / 30F); i++) {
34                 int x = rd.Next( rect.Width );
35                 int y = rd.Next( rect.Height );
36                 g.FillEllipse( brush, x, y, 23 );
37             }
38         }

      这里使用的是一个比较特别的笔刷HatchBrush,这个笔刷可以绘制出一些比较特别的效果,例如绘制验证码背景时候用到的HatchStyle.SmallConfetti ,绘制最上层噪点用的HatchStyle.Weave。灵活运用这些花纹的话,可以绘制出各种效果的验证码。当然wojilu的源代码并不是没有任何问题的,毕竟只有一个人在开发。这里的m这个变量看不出什么意义。

关于我记录系统的验证码,已经做了很好的封装了,您可以直接使用,具体的使用方法参见官网文档:

http://www.wojilu.com/Common/Page/71

 

MSDN参考:

ImageAttributes:

http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.imageattributes.aspx

ImageAttributes.SetRemapTable:

http://msdn.microsoft.com/zh-cn/library/system.drawing.imaging.imageattributes.setremaptable.aspx

ColorMatrix :

http://msdn.microsoft.com/en-us/library/system.drawing.imaging.colormatrix.aspx

 

我记录网址 http://www.wojilu.com/

欢迎大家加入我记录开发团队

 

作者: magicDict 发表于 2011-06-13 09:16 原文链接

评论: 1 查看评论 发表评论


最新新闻:
· 百思买财务官接任亚太负责人 不放弃中国市场(2011-06-13 16:57)
· 谷歌地图面临7月1日大限 搜狗开挖谷歌墙角(2011-06-13 16:56)
· 关于某公司捏造事实中伤永中Office的严正声明(2011-06-13 16:54)
· 细胞变激光(2011-06-13 16:42)
· HTC称与微软合作稳固 不排斥进一步收购(2011-06-13 16:39)

编辑推荐:自己动手开发编译器(四)利用DFA转换表建立扫描器

网站导航:博客园首页  我的园子  新闻  闪存  小组  博问  知识库

相关 [记录 网站 系统] 推荐:

我记录网站综合系统 -- 技术原理解析[2:C# 水印和验证码的制作]

- brett80 - 博客园-首页原创精华区
代码位置:wojilu\Drawing\Watermark.cs. 水印的定义:水印一般是指在图片上的一些版权信息文字,或者为了某种目的而对原始图片上附加一些图形或者文字. 水印的基本制作方法就是使用GDI+的方法在图片的制定位置上绘制文字或者图片. 说到GDI+,一般用于Winform对于GUI的绘制,例如文本编辑器的制作,就是使用GDI函数绘制文字在窗体表面.

车牌识别系统开发记录(三) 字符识别

- - CSDN博客综合推荐文章
这篇博文来谈谈车牌的字符识别. 目前,车牌字符识别算法主要是基于模板匹配、特征匹配或神经网络的方法. 在本文中我们主要来说说基于神经网络的字符识别方法,采用的是OpenCV中的CvANN_MLP. 关于神经网络的具体细节,可以参考我以前的博文:. BP神经网络解析及Matlab实现. 更加细节的东西可以查看如下参考文献:.

大型网站系统架构粗探

- - 网站架构_搜搜博客搜索
  软件架构有很多种定义,下面是卡内基梅隆大学软件研究所关于软件架构的定义:.   软件架构是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计. 软件架构描述的对象是直接构成系统的抽象组件. 各个组件之间的连接则明确和相对细致地描述组件之间的通讯. 在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象.

社交网站的使用记录能够预测各种个人信息

- - 心理科学流出版
在互联网时代,隐私泄露已经成为一个非常普遍的问题. 近期的一项 研究表明,即使你没有把个人信息直接放到网上,只要提供了你的社交网络使用记录,统计模型就能把你的各种信息相对准确地推算出来. 来自剑桥大学的Kosinski等人通过Facebook上的应用收集了58000人的数据,包括他们的“Like”记录、人口学信息,以及各种心理测验的分数.

视频学习网站学习时长实时记录-性能优化实践

- - CSDN博客系统运维推荐文章
一、     应用场景描述. 系统主要为教师在线学习提供服务,其中视频学习网站支持教师在线视频学习,教师在视频学习过程中其学习过程会被记录下来. 每个专题下对应多个教学视频,每个教学视频时长不尽一致. 现在的记录规则是:教师在看视频的时候,视频所在的页面每分钟提交一次请求,记录该视频已学习时长,并将该记录更新到数据库.

高效稳定的大型网站系统架构分析(转)

- - 网站架构_搜搜博客搜索
  千万人同时访问的网站,一般是有很多个数据库同时工作,说明白一点就是数据库集群和并发控制,这样的网站实时性也是相对的. 这些网站都有一些共同的特点:数据量大,在线人数多,并发请求多,pageview高,响应速度快. 总结了一下各个大网站的架构,主要提高效率及稳定性的几个地方包括:.     程序开发是一方面,系统架构设计(硬件+网络+软件)是另一方面.

大流量、高并发的网站的底层系统架构

- - 企业架构 - ITeye博客
大流量、高并发的网站的底层系统架构. [转载自] http://www.webjx.com/webmanage/experience-25319.html. 动态应用,是相对于网站静态内容而言, 是指以c/c++、php、Java、perl、.net等 服务器端语言开发的网络应用软件,比如论坛、网络相册、交友、BLOG等常见应用.

在线状态服务在网站系统中的应用

- - idea's blog
我的前一篇博客文章” 谈谈Facebook的聊天系统架构“, 对Facebook的聊天系统架构进行了分析. 其中的有些思想和系统划分, 对即使不是做聊天系统, 如一般的网站系统, 也是很有借鉴意义的. 例如其中的在线状态服务器(Presence).. 在线状态服务, 是这样的一个服务, 它维护了网站当前的在线用户列表, 接受其它模块的查询.

Piwik 2.1.0 发布,网站访问统计系统

- - 开源中国社区最新新闻
Piwik 2.1.0 发布,此版本主要更新内容如下:. Archiving 巨大的性能提升. 设备检测的 bug 修复和性能改进. 新的默认 MySql 数据库类型(InnoDB). 新的 Marketplace 插件——HTTP Authentication. Piwik是一套基于PHP5+MySQL技术构建的开源网站访问统计系统,前身是 phpMyVisites.

使用varnish + nginx + lua搭建网站的降级系统

- - 博学无忧
通常一个网站数据库挂掉后,后果将是非常严重的. 对于一些网站来说,当数据库挂掉后,如果能提供基本的浏览服务,也是不错的. 本文将尝试使用varnish + nginx + lua 搭建网站降级系统来实现整个目标. 降级方案的目标是,当网站出现致命故障时(如出现500错误,不能提供服务),可以把缓存的页面数据展现给用户.