早上,一哥儿发来添加图片水印的资料。有三个信息,如下:
             xx 09:57:35
 
王二狗 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
 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 /** <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
 37            switch(_watermarkPosition)
 38            {
 39                case "WM_TOP_LEFT":
 40                    xpos = 10;
 41                    ypos = 10;
 42                    break;
 43                case "WM_TOP_RIGHT":
 44                    xpos = ((_width - watermark.Width) - 10);
 45                    ypos = 10;
 46                    break;
 47                case "WM_BOTTOM_RIGHT":
 48                    xpos = ((_width - watermark.Width) - 10);
 49                    ypos = _height - watermark.Height - 10;
 50                    break;
 51                case "WM_BOTTOM_LEFT":
 52                    xpos = 10;
 53                    ypos = _height - watermark.Height - 10;
 54                    break;
 55            }
 56
 57            picture.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
 58
 59
 60            watermark.Dispose();
 61            imageAttributes.Dispose();
 62        }


     如果你能耐着心读到这里,你可以分辨一下,这两个加水印的函数和网上别人的代码有什么不同了。你也可以发现为什么网上的代码不能运行通过了。你只要动下小手,调试下就知道原因了。

     最后做得效果很好,附上帅图1,2,3
  带图片水印的。带文字水印

   你看看效果不错吧,这些水印都是设为放在右下角的。至于带图片的那张怎么位置不像在右下角,是因为背景图片太小,水印图片太大的原因。我只是随便做了下测试。
      如果你也是像我这样菜鸟的话,可能对你有点用处。大侠就不用看了。我写出来,其实是觉得网上连一些基础的代码都写的不好,还抄来抄去,更严重的是还是错误的。
 

王传炜,2005-5-31