zoukankan      html  css  js  c++  java
  • [转]c# 添加图片水印,可以指定水印位置+生成缩略图

     c# 添加图片水印,可以指定水印位置+生成缩略图     CSDN Blog推出文章指数概念,文章指数是对Blog文章综合评分后推算出的,综合评分项分别是该文章的点击量,回复次数,被网摘收录数量,文章长度和文章类型;满分100,每月更新一次。
      早上,一哥儿发来添加图片水印的资料。有三个信息,如下:
                
    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, 00, 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, 1010);
    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), 00, 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, 00, 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(15300,0));
    50            picture.DrawString(_watermarkText, crFont, semiTransBrush2, xpos+1, ypos+1, StrFormat);
    51
    52            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153255255255));
    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(25502550);
     17            colorMap.NewColor = Color.FromArgb(0000);
     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.0f0.0f},
     24                                                new float[] {0.0f,  1.0f,  0.0f,  0.0f0.0f},
     25                                                new float[] {0.0f,  0.0f,  1.0f,  0.0f0.0f},
     26                                                new float[] {0.0f,  0.0f,  0.0f,  0.3f0.0f},
     27                                                new float[] {0.0f,  0.0f,  0.0f,  0.0f1.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), 00, 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
      带图片水印的。带文字水印

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



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=826045

  • 相关阅读:
    [na]ip数据包格式
    [js]浏览器同源策略(same-origin policy)
    [sql] 同库表(结构)的备份和sql聚合&navicat使用
    [svc]tcp三次握手四次挥手&tcp的11种状态(半连接)&tcp的time-wait
    [svc]ip地址划分
    [css]单/多行居中&字体设置
    时间戳转为C#格式时间
    windows 8 中 使用 httpclient
    oralce 查看是否启动 登陆 创建用户 常用命令小记
    SQL递归查询(with cte as)
  • 原文地址:https://www.cnblogs.com/SummerRain/p/1052809.html
Copyright © 2011-2022 走看看