[已解决问题] Vs2003下C# 图片加水印 半透明文字?
提问时间: 2008-01-25 11:51
悬赏分: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"));
  }

-----

这个是偶的加水印文字的代码。。求透明文字代码。。分不在多。。学习当先。。

提问者:彭成刚 - 初学一级

问题补充:就我个人的理解吧。。是不是需要把文字做成个透明图片。。再把图片的透明度调调,再把图片贴到水印图片上哇。。个人猜的。。

所有回答(2)
using (Brush brush = new SolidBrush(Color.FromArgb(128, Color.Red))) { g.DrawString("水印", font1, brush, 1, 1); } 你的代码中存在比较严重的GDI泄漏,使用完后,需要Dispose. :)
8个月前   回答者:Colin Han - 老鸟四级
它这个代码不在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个月前   回答者:hoodlum1980 - 菜鸟二级
评论
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没什么问题。
   您需要登录以后才能回答!
 

我要提问

我的问题


快到期问题

> 问题排行榜

相关内容

相关链接