悬赏分:5 浏览:1462 次
也是帮个朋友问的。。我的代码是加文字水印的。。文字就在上面了。。可是客户非要半透明文字的。。我是找不到了。。寻求帮助了。。
------
public void shuiyin()
{
System.Drawing.Bitmap image = new System.Drawing.Bitmap(Server.MapPath("shuiyin/shuiyintu.jpg"));
Graphics g = Graphics.FromImage(image);
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0,0,image.Width,image.Height),Color.Red,Color.Red,1.2f,true);
Font font1 = new Font("宋体",22);
g.DrawString("彭彭水印",font1,brush,1,1);
g.Save();
image.Save(Server.MapPath("shuiyin/shuiyintu1.jpg"));
}
-----
这个是偶的加水印文字的代码。。求透明文字代码。。分不在多。。学习当先。。
|
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.Red)))
{
g.DrawString("水印", font1, brush, 1, 1);
}
你的代码中存在比较严重的GDI泄漏,使用完后,需要Dispose. :) 它这个代码不在onpaint里面,是在某个函数体里,所以资源应该是被托管的,无所谓dispose了吧。 透明度贴图则不能直接绘制到原图上,步骤可以如下,先单独测量字符串。 下面给你一个我通过了我自己的测试的刚写的代码。注意,没有检查水印的边界是否超出图片范围(如果水印超出图片范围,将导致访问超出范围的内存而产生异常)。注意:使用下面的代码还要把在项目属性里把允许不安全代码的选项勾选。 /// <summary> /// 给一个位图绘制水印文字 /// </summary> /// <param name="text">水印文本</param> /// <param name="x">起始点</param> /// <param name="y">起始点</param> /// <param name="opacity">不透明度,0~1</param> private Bitmap DrawWatermark(Image image,string text, Font font,Brush brush,int x,int y,double opacity) { Bitmap bm1 = new Bitmap(this.m_Bitmap); Graphics g1=Graphics.FromImage(bm1); //测量水印文字的大小,然后申请一个新的位图 SizeF sizef=g1.MeasureString(text,font); Bitmap bm2=new Bitmap((int)sizef.Width,(int)sizef.Height); Graphics g2=Graphics.FromImage(bm2); g2.DrawImage(bm1, 0,0,new Rectangle(x, y, bm2.Width, bm2.Height),GraphicsUnit.Pixel); g2.DrawString(text,font,brush,0,0); BitmapData data1=bm1.LockBits(new Rectangle(0,0,bm1.Width,bm1.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb); BitmapData data2=bm2.LockBits(new Rectangle(0,0,bm2.Width,bm2.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb); unsafe { byte* p1=(byte*)(void*)data1.Scan0; byte* p2=(byte*)(void*)data2.Scan0; for(int j=0;j<bm2.Height;j++) { for(int i=0;i<bm2.Width;i++) { p1[(y+j) * data1.Stride+ (x+i) *3]=(byte)(p1[(y+j)*data1.Stride+(x+i)*3]*(1-opacity)+opacity*p2[j*data2.Stride+i*3]); p1[(y+j) * data1.Stride + (x+i) * 3 + 1] = (byte)(p1[(y+j) * data1.Stride + (x+i) * 3 + 1] * (1-opacity) + opacity * p2[j * data2.Stride + i * 3+1]); p1[(y+j) * data1.Stride + (x+i) * 3 + 2] = (byte)(p1[(y+j) * data1.Stride + (x+i) * 3 + 2] * (1-opacity) + opacity* p2[j * data2.Stride + i * 3+2]); } } bm1.UnlockBits(data1); bm2.UnlockBits(data2); } return bm1; } 函数里的bm2就是水印,当然如果你的水印是一个图片也可以,上面的函数只要稍加修改作为参数传进去,但水印图片需要指定透明色。然后可以用类似上面的方法用imageattibutes指定透明色直接绘制好水印图片好按照同样的方法进行合成,或者在处理像素数据的时候判断根据是否是透明色决定如何处理(这会比较复杂些)。 |
|
8个月前 carysun : 搜索一下iText这个库,是个java开源的类库,主要作用是处理pdf 我用他对pdf文件加过水印,效果还是不错的 它有一个对应.net的库,叫iTextSharp,对图片加水印我没测试过 不过可以将图片转成pdf |
|
8个月前 Colin Han : >> 它这个代码不在onpaint里面,是在某个函数体里,所以资源应该是被托管的,无所谓dispose了吧。 严重的误解。任何时候,你自己构造的对象都需要你自己手动释放。除非你确认这个对象被其它对象使用中。 .NET 2.0在Windows Handle的处理方面进行了增强。引入了SafeHandle的概念。因此,大多时候GC会帮助你回收Windows Handle。但是,这一点并不得到任何保证。作为好的习惯,应该使用后自己手动释放。 |
|
4个月前 hoodlum1980 : 严重的误解。任何时候,你自己构造的对象都需要你自己手动释放。除非你确认这个对象被其它对象使用中。 我认为他在函数中创建的临时GDI对象都属于托管对象,没有任何非托管资源,因此它这里不调用dispose没什么问题。 |