您的位置:首页 > 编程语言 > C#

给图片加透明度水印的方法(c#)

2008-01-28 14:21 239 查看
刚才在提问区解答了一个问题,即如何给图片加半透明度水印,实际上由于透明度算法是最早被发现也是最简单和基本的算法之一,因此这个方法实际上很直观。这里单独发帖再来解释下这个问题。首先我们强调一下opacity的概念,是“不透明度”,它表示的是两个图层之间的关系,即该属性隶属于本图层,它表示与本图层下面图层之间的像素合成关系,当opacity=100%时,表示本图层完全不透明,因此下面的像素完全被遮挡。当opacity=0时,表示本图层完全透明,即能看到下面的图层。这是photoshop中最基本的一个算法,表达如下:

像素结果=底部图层*(1-opacity)+本图层*opacity;

当有多个图层x0,x1,x2混合时,表达如下:(最底层的不透明度为1)

x=((1-k1)x0+k1*x1)(1-k2)+k2*x2= (1-k1)(1-k2)x0 + k1(1-k2)x1 + k2*x2;

那么绘制透明度水印的方法也就非常直观了,因为类库中的ImageAttributes属性里面并没有提供像素合成的绘制选项,因此我们自己实现上面的算法。方法是:首先准备一个小的水印图片,我们先把原图在水印下面的部分绘制上去,然后在吧水印的文本或图片绘制上去,然后把原图和水印图片的内存数据锁定(防止操作系统移动内存),然后直接用上面的算法改写原图的位图数据,解锁内存即得到最终加了水印的图片。

代码如下:下面是绘制文本类型的水印,只需提供水印文本内容,绘制起始坐标即可。注意,为了简单直观起见,代码中都没有做参数验证,例如水印是否超出原图范围,如果超出范围将引发对超过内存边界的访问限制(引发异常)。下面使用了unsafe代码,因此项目属性->Build中,应勾选允许不安全代码,否则无法编译。 在下面代码中的定位方式是非常熟悉的。再次强调的是以下的概念:

scan0:指针,内存数据的起始地址。(换句话说,就是指向第一个扫描行第一个像素的Blue)。

bpp:bit per pixel。

stride:扫描行宽度,=width*bpp/8 并在结尾补0~3个字节的0,以凑齐到4字节整数倍。

之所以横坐标乘以3是因为我们锁定的方式是24bppRgb(最后一个参数指定了数据的bpp),这意味这每个像素占据了3个字节,因此i要乘以3来跳跃到下一个像素。如果用32bppRGB锁定,则每个像素在内存占据4字节,相应的i应该乘以4。

Code-图片水印

/// <param name="image">原图</param>

/// <param name="wmImg">水印图片</param>

/// <param name="key">透明色</param>

/// <param name="x">起始点</param>

/// <param name="y"></param>

/// <param name="opacity">不透明度</param>

/// <returns></returns>

private Bitmap DrawWatermark(Image image, Bitmap wmImg, Color key,int x, int y, double opacity)

{

Bitmap bm1 = new Bitmap(image); //克隆原图,它也是我们的返回值

Bitmap bm2 = new Bitmap(wmImg.Width, wmImg.Height); //准备的水印图片

Graphics g2 = Graphics.FromImage(bm2);

ImageAttributes att = new ImageAttributes();

att.SetColorKey(key, key, ColorAdjustType.Bitmap); //设定透明色

g2.DrawImage(bm1, 0, 0, new Rectangle(x, y, bm2.Width, bm2.Height), GraphicsUnit.Pixel);

g2.DrawImage(wmImg, new Rectangle(0,0,bm2.Width,bm2.Height),0, 0,bm2.Width,bm2.Height,GraphicsUnit.Pixel,att);

g2.Dispose();

。。。。这里的代码和上面的方法代码相同,因此省略

return bm1;

}

以上两种效果的截图:

(1)

(2)


源代码的下载链接:(该项目里还包括我对Photoshop中置换滤镜的模拟代码,以及在水波特效控件原理解释那篇文中的水波置换图生成器。)

http://files.cnblogs.com/hoodlum1980/PsFilters.rar
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: