早上,一哥儿发来添加图片水印的资料。有三个信息,如下:
xx 09:57:35
http://index.cnblogs.com/archive/2004/10/20/54498.aspx
王二狗 09:57:51
好的,我看看
xx 09:58:12
http://www.iyuanma.com/info/18/17026_200592663244.htm
xx 10:07:00
http://www.codefans.com/CodeView/CodeView_12043.html
xx 10:07:18
你看看现成的组件能不能用
几分钟后,我就发现第二个网址的内容是copy第一个的(也许是相反),真是天下文章一大抄。于是我对那条说有什么组件的东东很感兴趣,下下来一看,吐血,就是一段代码,完全copy第一个文章里的,什么组件啊。真是能欺骗人。
算了,自己动手,丰衣十足。想起上个月做相册的开发,用到了Gallery开源项目的东西。那里面有填加水印的,并且功能比较强大,能设定位置。不像上面的资料不能调整水印位置,水印效果估计也不好,毕竟就那几行。其实后来我发现那段代码还是错的,调试通过不了,修改后才能用,至于错在那里在后面介绍。
我们先看看哥儿给我的资料里的代码:
原来的代码:
1 private void Btn_Upload_Click(object sender, System.EventArgs e)
2 {
3 if(UploadFile.PostedFile.FileName.Trim()!="")
4 {
5 //上传文件
6 string extension = Path.GetExtension(UploadFile.PostedFile.FileName).ToUpper();
7 string fileName = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
8 string path = Server.MapPath(".") + "/UploadFile/" + fileName + extension;
9 UploadFile.PostedFile.SaveAs(path);
10
11 //加文字水印,注意,这里的代码和以下加图片水印的代码不能共存
12 System.Drawing.Image image = System.Drawing.Image.FromFile(path);
13 Graphics g = Graphics.FromImage(image);
14 g.DrawImage(image, 0, 0, image.Width, image.Height);
15 Font f = new Font("Verdana", 32);
16 Brush b = new SolidBrush(Color.White);
17 string addText = AddText.Value.Trim();
18 g.DrawString(addText, f, b, 10, 10);
19 g.Dispose();
20
21 //加图片水印
22 System.Drawing.Image image = System.Drawing.Image.FromFile(path);
23 System.Drawing.Image copyImage = System.Drawing.Image.FromFile( Server.MapPath(".") + "/Alex.gif");
24 Graphics g = Graphics.FromImage(image);
25 g.DrawImage(copyImage, new Rectangle(image.Width-copyImage.Width, image.Height-copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, GraphicsUnit.Pixel);
26 g.Dispose();
27
28 //保存加水印过后的图片,删除原始图片
29 string newPath = Server.MapPath(".") + "/UploadFile/" + fileName + "_new" + extension;
30 image.Save(newPath);
31 image.Dispose();
32 if(File.Exists(path))
33 {
34 File.Delete(path);
35 }
36
37 Response.Redirect(newPath);
38 }
39 }
于是我把Gallery里的代码整理了下。如下:
图片上传函数,进行判断是否加水印,做出两种处理方式:
1 /// <summary>
2 /// 上传图片代码
3 /// </summary>
4 /// <param name="image_file">HtmlInputFile控件</param>
5 /// <param name="ImgPath">存放的文件夹绝对位置</param>
6 /// <param name="ImgLink">生成的图片的名称带后缀</param>
7 /// <returns></returns>
8 public bool UpPic(System.Web.UI.HtmlControls.HtmlInputFile image_file,string ImgPath,string ImgLink )
9 {
10 if(image_file.PostedFile.FileName!=null && image_file.PostedFile.FileName.Trim()!="")
11 {
12 try
13 {
14 if( !System.IO.Directory.Exists(ImgPath))
15 {
16 System.IO.Directory.CreateDirectory( ImgPath);
17 }
18 //生成缩略图
this.GreateMiniImage((ImgPath+ "\\"+"old_"+ImgLink),(ImgPath+ "\\"+"mini_"+ImgLink),50,50);
19 //如果显示水印
20 if(ShowWatermark)
21 {
22 image_file.PostedFile.SaveAs(ImgPath+ "\\" +"old_"+ImgLink);
23 //加水印
24 this.addWaterMark((ImgPath+ "\\"+"old_"+ImgLink),(ImgPath+ "\\"+ImgLink));
25
26
27
28 }
29 else
30 {
31 image_file.PostedFile.SaveAs(ImgPath+ "\\" +ImgLink);
32
33
34 }
35 return true;
36 }
37
38 catch
39 {
40 return false;
41 }
42 }
43 else
44
45 {
46 return false;
47 }
48
49 }
加水印的函数如下:
填加图片函数,需要下面两个函数的支持,当然也可以写到一起,不过那看起来就很冗长了。
1 /// <summary>
2 /// 添加图片水印
3 /// </summary>
4 /// <param name="oldpath">原图片绝对地址</param>
5 /// <param name="newpath">新图片放置的绝对地址</param>
6 private void addWaterMark(string oldpath,string newpath)
7
8 {
9 try
10 {
11
12 System.Drawing.Image image = System.Drawing.Image.FromFile(oldpath);
13
14 Bitmap b = new Bitmap(image.Width, image.Height,PixelFormat.Format24bppRgb);
15 Graphics g = Graphics.FromImage(b);
16 g.Clear(Color.White);
17 g.SmoothingMode = SmoothingMode.HighQuality;
18 g.InterpolationMode = InterpolationMode.High;
19
20 g.DrawImage(image, 0, 0, image.Width, image.Height);
21
22 if(如果需要填加水印)
23 {
24 switch(水印类型)
25 {
26 //是图片的话
case "WM_IMAGE":
27 this.addWatermarkImage( g,Page.Server.MapPath(Watermarkimgpath),WatermarkPosition,image.Width,image.Height);
28 break;
29 //如果是文字
case "WM_TEXT":
30 this.addWatermarkText( g, WatermarkText,WatermarkPosition
31 ,image.Width,image.Height);
32 break;
33 }
34
35 b.Save(newpath);
36 b.Dispose();
37 image.Dispose();
38 }
39
40 }
41 catch
42 {
43
44 if(File.Exists(oldpath))
45 {
46 File.Delete(oldpath);
47 }
48 }
49 finally
50 {
51
52 if(File.Exists(oldpath))
53 {
54 File.Delete(oldpath);
55 }
56
57
58 }
59
60
61
62
63
64
65 }
1/// <summary>
2 /// 加水印文字
3 /// </summary>
4 /// <param name="picture">imge 对象</param>
5 /// <param name="_watermarkText">水印文字内容</param>
6 /// <param name="_watermarkPosition">水印位置</param>
7 /// <param name="_width">被加水印图片的宽</param>
8 /// <param name="_height">被加水印图片的高</param>
9 private void addWatermarkText( Graphics picture,string _watermarkText,string _watermarkPosition,int _width,int _height)
10 {
11 int[] sizes = new int[]{16,14,12,10,8,6,4};
12 Font crFont = null;
13 SizeF crSize = new SizeF();
14 for (int i=0 ;i<7; i++)
15 {
16 crFont = new Font("arial", sizes[i], FontStyle.Bold);
17 crSize = picture.MeasureString(_watermarkText, crFont);
18
19 if((ushort)crSize.Width < (ushort)_width)
20 break;
21 }
22
23 float xpos = 0;
24 float ypos = 0;
25
26 switch(_watermarkPosition)
27 {
28 case "WM_TOP_LEFT":
29 xpos = ((float)_width * (float).01) + (crSize.Width / 2);
30 ypos = (float)_height * (float).01;
31 break;
32 case "WM_TOP_RIGHT":
33 xpos = ((float)_width * (float).99) - (crSize.Width / 2);
34 ypos = (float)_height * (float).01;
35 break;
36 case "WM_BOTTOM_RIGHT":
37 xpos = ((float)_width * (float).99) - (crSize.Width / 2);
38 ypos = ((float)_height * (float).99) - crSize.Height;
39 break;
40 case "WM_BOTTOM_LEFT":
41 xpos = ((float)_width * (float).01) + (crSize.Width / 2);
42 ypos = ((float)_height * (float).99) - crSize.Height;
43 break;
44 }
45
46 StringFormat StrFormat = new StringFormat();
47 StrFormat.Alignment = StringAlignment.Center;
48
49 SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0,0));
50 picture.DrawString(_watermarkText, crFont, semiTransBrush2, xpos+1, ypos+1, StrFormat);
51
52 SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
53 picture.DrawString(_watermarkText, crFont, semiTransBrush, xpos, ypos, StrFormat);
54
55
56 semiTransBrush2.Dispose();
57 semiTransBrush.Dispose();
58
59
60
61 }
//代码已经修改,可以按比率还填加图片水印,不过如果背景图片和水印图片太不成比率的话(指水印图片要大于背景图片的1/4),出来的效果不是很好。
1 /// <summary>
2 /// 加水印图片
3 /// </summary>
4 /// <param name="picture">imge 对象</param>
5 /// <param name="WaterMarkPicPath">水印图片的地址</param>
6 /// <param name="_watermarkPosition">水印位置</param>
7 /// <param name="_width">被加水印图片的宽</param>
8 /// <param name="_height">被加水印图片的高</param>
9 private void addWatermarkImage( Graphics picture,string WaterMarkPicPath,string _watermarkPosition,int _width,int _height)
10 {
11 Image watermark = new Bitmap(WaterMarkPicPath);
12
13 ImageAttributes imageAttributes = new ImageAttributes();
14 ColorMap colorMap = new ColorMap();
15
16 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
17 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
18 ColorMap[] remapTable = {colorMap};
19
20 imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
21
22 float[][] colorMatrixElements = {
23 new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f},
24 new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
25 new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f},
26 new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},
27 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}
28 };
29
30 ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
31
32 imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
33
34 int xpos = 0;
35 int ypos = 0;
36 int WatermarkWidth=0;
37 int WatermarkHeight=0;
38 double bl=1d;
39 //计算水印图片的比率
40 //取背景的1/4宽度来比较
41 if((_width>watermark.Width*4)&&(_height>watermark.Height*4))
42 {
43 bl=1;
44 }
45 else if((_width>watermark.Width*4)&&(_height<watermark.Height*4))
46 {
47 bl=Convert.ToDouble(_height/4)/Convert.ToDouble(watermark.Height);
48
49 }else
50
51 if((_width<watermark.Width*4)&&(_height>watermark.Height*4))
52 {
53 bl=Convert.ToDouble(_width/4)/Convert.ToDouble(watermark.Width);
54 }
55 else
56 {
57 if((_width*watermark.Height)>(_height*watermark.Width))
58 {
59 bl=Convert.ToDouble(_height/4)/Convert.ToDouble(watermark.Height);
60
61 }
62 else
63 {
64 bl=Convert.ToDouble(_width/4)/Convert.ToDouble(watermark.Width);
65
66 }
67
68 }
69
70 WatermarkWidth=Convert.ToInt32(watermark.Width*bl);
71 WatermarkHeight=Convert.ToInt32(watermark.Height*bl);
72
73
74
75 switch(_watermarkPosition)
76 {
77 case "WM_TOP_LEFT":
78 xpos = 10;
79 ypos = 10;
80 break;
81 case "WM_TOP_RIGHT":
82 xpos = _width - WatermarkWidth - 10;
83 ypos = 10;
84 break;
85 case "WM_BOTTOM_RIGHT":
86 xpos = _width - WatermarkWidth - 10;
87 ypos = _height -WatermarkHeight - 10;
88 break;
89 case "WM_BOTTOM_LEFT":
90 xpos = 10;
91 ypos = _height - WatermarkHeight - 10;
92 break;
93 }
94
95 picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
96
97
98 watermark.Dispose();
99 imageAttributes.Dispose();
100 }
生成缩略图函数
1
2 /// <summary>
3 /// 生成缩略图
4 /// </summary>
5 /// <param name="oldpath">原图片地址</param>
6 /// <param name="newpath">新图片地址</param>
7 /// <param name="tWidth">缩略图的宽</param>
8 /// <param name="tHeight">缩略图的高</param>
9 private void GreateMiniImage(string oldpath,string newpath,int tWidth, int tHeight)
10 {
11
12 try
13 {
14
15 System.Drawing.Image image = System.Drawing.Image.FromFile(oldpath);
16 double bl=1d;
17 if((image.Width<=image.Height)&&(tWidth>=tHeight))
18 {
19 bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);
20 }
21 else if((image.Width>image.Height)&&(tWidth<tHeight))
22 {
23 bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);
24
25 }
26 else
27
28 if((image.Width<=image.Height)&&(tWidth<=tHeight))
29 {
30 if(image.Height/tHeight>=image.Width/tWidth)
31 {
32 bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);
33
34 }
35 else
36 {
37 bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);
38 }
39 }
40 else
41 {
42 if(image.Height/tHeight>=image.Width/tWidth)
43 {
44 bl=Convert.ToDouble(image.Height)/Convert.ToDouble(tHeight);
45
46 }
47 else
48 {
49 bl=Convert.ToDouble(image.Width)/Convert.ToDouble(tWidth);
50
51 }
52
53 }
54
55
56 Bitmap b = new Bitmap(image ,Convert.ToInt32(image.Width/bl), Convert.ToInt32(image.Height/bl));
57
58 b.Save(newpath);
59 b.Dispose();
60 image.Dispose();
61
62
63 }
64 catch
65 {
66
67
68 }
69
70 }
如果你能耐着心读到这里,你可以分辨一下,这两个加水印的函数和网上别人的代码有什么不同了。你也可以发现为什么网上的代码不能运行通过了。你只要动下小手,调试下就知道原因了。
最后做得效果很好,附上帅图1,2,3
带图片水印的。带文字水印
你看看效果不错吧,这些水印都是设为放在右下角的。
至于带图片的那张怎么位置不像在右下角,是因为背景图片太小,水印图片太大的原因。
我只是随便做了下测试。新的效果图已经放上。
如果你也是像我这样菜鸟的话,可能对你有点用处。大侠就不用看了。我写出来,其实是觉得网上连一些基础的代码都写的不好,还抄来抄去,更严重的是还是错误的。
最新帅图:
缩略图:
由于原图太大上传不上来,只得把对比图发上来。