水印图片的制作及常用的图像处理(C#)

  水印制作就是简要来说利用GDI+的函数,进行原图和水印图片的合成,或者在原图上配置文字。

  水印制作的关键函数:

  1. DrawString方法绘制文字
  2. DrawImage方法绘制图片

这两个函数有比较多重载,具体请参考MSDN。

说到GDI+,他一般用于Winform对于GUI的绘制,例如桌面上的窗体。其实GDI不仅可以绘制窗体,它可以绘制一切的表面图像。

  其中Graphics绘制图像最核心的类,该对象就像一张画图画的画布,我们可以绘制图像的方法在其上绘图。一个应用程序如果需要绘制和着色,它就必须使用该对象。

此外不得不说还有两个对象:Image类和BitMap类。这两个对象也比较重要。

首先是Image类,该类提供了位图和元文件操作的函数,它是一个抽象类,不能实例化,只能用作基类,我们主要用它来加载一些文件,生成Image对象,以便对位图进一步操作。

其次是BitMap对象,用于由像素数据定义的图像,它也是进行图像处理的主要类。我们可以取得或者设置它的一些属性,还可用它读入和保存一些图像。

下面就进入我们的主题:

一、绘制文字水印

View Code
 private static void drawText(Graphics g, String wmText, Font font, PointF p, StringFormat format)
        {

            SolidBrush brush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
            g.DrawString(wmText, font, brush, p, format);

            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置g的呈现质量
            //用指定的笔刷,和字体绘制文字
            SolidBrush brush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
            g.DrawString(wmText, font, brush2, new PointF(p.X + 1, p.Y + 1), format);
  
        }

二、绘制图片水印

  图片水印主要是两个图像的合成,重点是要设置图片的水印的透明度,透明度一般降为原来的30%,这里将使用colorMatrix来做。矩阵在很多地方的被合使用,主要有矩阵进行像素的高速变换(其它方法处理速度相对较慢),特别是变换的地方。仔细观察矩阵对角线数字,1,1,1,0.3,1;这些是倍数运算因子,对应RGBAW的变换倍数。RGB不变,透明度为原来的0.3倍。通过这种方法就将图片的透明度降低了。

设置图像特性,主要是透明度的代码:

View Code
       private static ImageAttributes getImageAttributes()
        {
             ImageAttributes imgAttr = new ImageAttributes();

             ColorMap colorMap = new ColorMap();
             colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
             colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
             ColorMap[] remapTable = { colorMap };

             imgAttr.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

             float[][] colorMatrixElements = { 
                                           new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
                                           new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                           new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                           new float[] {0.0f,  0.0f,  0.0f,  (float)(ImageTransparencyNum/100.0), 0.0f},
                                           new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                        };

             ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
             imgAttr.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

             return imgAttr;
        }

绘制图片水印核心的代码:

View Code
       public static Bitmap AddWaterMark_IMG(String srcPath, String watermarkPath, WaterMarkPosition wp = WaterMarkPosition.BottomRight)
        {
            using (Image src = Image.FromFile(srcPath))
            {
                using (Bitmap bm = new Bitmap(srcPath))
                {
                    using (Graphics g = Graphics.FromImage(bm))
                    {
                        using (Image wm = Image.FromFile(watermarkPath))
                        {
                           
                            ImageAttributes imgAttr = getImageAttributes();
                             Rectangle rect = getPicRectangle(src, wm, wp);

                            g.DrawImage(wm, rect, 0, 0, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr);

                            return new Bitmap((Image)(bm.Clone()));

                        }
                    }
                }
            }

        }

有时灰度化图像也比较常用,这个如果也用像素法处理也是较慢的,我们也采用矩阵处理

View Code
public static Bitmap GrayPicuure(String srcPicturePath)
        {
            using (Bitmap currentBitmap = new Bitmap(srcPicturePath))
            {
                using (Graphics g = Graphics.FromImage(currentBitmap))
                {
                    using (ImageAttributes ia = new ImageAttributes())
                    {       
                        float[][] colorMatrix = {     
                                            new   float[]   {0.299f,   0.299f,   0.299f,   0,   0},
                                            new   float[]   {0.587f,   0.587f,   0.587f,   0,   0},
                                            new   float[]   {0.114f,   0.114f,   0.114f,   0,   0},
                                            new   float[]   {0,   0,   0,   1,   0},
                                            new   float[]   {0,   0,   0,   0,   1}
                                            };
                        //颜色调整矩阵
                        ColorMatrix cm = new ColorMatrix(colorMatrix);

                        ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                        g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia);

                        return new Bitmap((Image)(currentBitmap.Clone()));
                    }
                }
            }
        }

此外我们在图像处理时也会翻转旋转图像,这里主要用Image类的RotateFlip方法处理

View Code
public static Bitmap RotateFlipPicture(String srcPicturePath, RotateFlipType RotateFlipType)
        {
            using (Image tmp = Image.FromFile(srcPicturePath))
            {
                tmp.RotateFlip(RotateFlipType);
                return new Bitmap(tmp);
            }   
        }

图像处理内容比较多,在此不一列举,这里只给出常用的,下面给出全部源代码

View Code
  1 /*
  2  * Copyright 2012 www.vision.net.cn
  3  * 
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  * 
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  * 
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 
 17 using System;
 18 using System.IO;
 19 using System.Drawing;
 20 using System.Drawing.Imaging;
 21 using System.Windows.Forms;
 22 
 23 namespace myDrawing
 24 {
 25     /// <summary>
 26     /// 水印的位置
 27     /// </summary>
 28     public enum WaterMarkPosition
 29     {
 30         /// <summary>
 31         /// 左上角
 32         /// </summary>
 33         TopLeft,
 34         /// <summary>
 35         /// 左下角
 36         /// </summary>
 37         BottomLeft,
 38         /// <summary>
 39         /// 右上角
 40         /// </summary>
 41         TopRight,
 42         /// <summary>
 43         /// 右下角
 44         /// </summary>
 45         BottomRight,
 46         /// <summary>
 47         /// 顶部中间
 48         /// </summary>
 49         TopCenter,
 50         /// <summary>
 51         /// 底部中间
 52         /// </summary>
 53         BottomCenter
 54     };
 55     /// <summary>
 56     /// 字体
 57     /// </summary>
 58     public enum myFont
 59     { 
 60         /// <summary>
 61         /// 字体:中文宋体
 62         /// </summary>
 63         宋体,
 64         /// <summary>
 65         /// 字体:中文楷体
 66         /// </summary>
 67         楷体,
 68         /// <summary>
 69         /// 字体:中文仿宋
 70         /// </summary>
 71         仿宋,
 72         /// <summary>
 73         /// 字体:中文黑体
 74         /// </summary>
 75         黑体,
 76         /// <summary>
 77         /// 字体:Arial
 78         /// </summary>
 79         Arial,
 80         /// <summary>
 81         /// 字体:Georgia
 82         /// </summary>
 83         Georgia
 84     }
 85     /// <summary>
 86     /// 水印工具
 87     /// </summary>
 88     public class Watermark
 89     {
 90         private static int imageTransparency=0;
 91         /// <summary>
 92         /// 水印图像的透明度,默认30%透明
 93         /// </summary>
 94         public static int ImageTransparencyNum
 95         {
 96             get { if (imageTransparency == 0)imageTransparency = 30; return imageTransparency; }
 97             set
 98             {
 99                 if (imageTransparency >=0 && imageTransparency <= 100) imageTransparency = value;
100             }
101         }
102         /// <summary>
103         /// 取得设置的图像特性,主要是透明度
104         /// </summary>
105         /// <returns></returns>
106         private static ImageAttributes getImageAttributes()
107         {
108              ImageAttributes imgAttr = new ImageAttributes();
109 
110              ColorMap colorMap = new ColorMap();
111              colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
112              colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
113              ColorMap[] remapTable = { colorMap };
114 
115              imgAttr.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
116 
117              float[][] colorMatrixElements = { 
118                                            new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
119                                            new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
120                                            new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
121                                            new float[] {0.0f,  0.0f,  0.0f,  (float)(ImageTransparencyNum/100.0), 0.0f},
122                                            new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
123                                         };
124 
125              ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
126              imgAttr.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
127 
128              return imgAttr;
129         }
130         /// <summary>
131         /// 添加图片水印:将原始图片添加图片水印之后存储
132         /// </summary>
133         /// <param name="srcPath">原图片绝对地址</param>
134         /// <param name="watermarkPath">水印图片路径</param>
135         /// <param name="wp">水印位置的枚举值</param>
136         public static Bitmap AddWaterMark_IMG(String srcPath, String watermarkPath, WaterMarkPosition wp = WaterMarkPosition.BottomRight)
137         {
138             using (Image src = Image.FromFile(srcPath))
139             {
140                 using (Bitmap bm = new Bitmap(srcPath))
141                 {
142                     using (Graphics g = Graphics.FromImage(bm))
143                     {
144                         using (Image wm = Image.FromFile(watermarkPath))
145                         {
146                            
147                             ImageAttributes imgAttr = getImageAttributes();
148                              Rectangle rect = getPicRectangle(src, wm, wp);
149 
150                             g.DrawImage(wm, rect, 0, 0, wm.Width, wm.Height, GraphicsUnit.Pixel, imgAttr);
151 
152                             return new Bitmap((Image)(bm.Clone()));
153 
154                         }
155                     }
156                 }
157             }
158 
159         }
160       
161         /// <summary>
162         /// 取得绘制水印的矩形
163         /// </summary>
164         /// <param name="src">原图像映像</param>
165         /// <param name="wm">水印图像映像</param>
166         /// <param name="wp">指定的水印位置枚举值WaterMarkPosition</param>
167         /// <returns></returns>
168         private static Rectangle getPicRectangle(Image src, Image wm, WaterMarkPosition wp)
169         {
170 
171             int xpos = 10;//水印图像X坐标
172             int ypos = 10;//水印图像y坐标
173 
174             switch (wp)
175             {
176                 case WaterMarkPosition.TopLeft:
177                     xpos = 10;
178                     ypos = 10;
179                     break;
180                 case WaterMarkPosition.TopCenter:
181                     xpos = src.Width / 2 - wm.Width / 2;
182                     ypos = 10;
183                     break;
184                 case WaterMarkPosition.TopRight:
185                     xpos = ((src.Width - wm.Width) - 10);
186                     ypos = 10;
187                     break;
188                 case WaterMarkPosition.BottomLeft:
189                     xpos = 10;
190                     ypos = src.Height - wm.Height - 10;
191                     break;
192                 case WaterMarkPosition.BottomRight:
193                     xpos = ((src.Width - wm.Width) - 10); 
194                     ypos = src.Height - wm.Height - 10;
195                     break;
196                 case WaterMarkPosition.BottomCenter:
197                     xpos = src.Width / 2 - wm.Width / 2;
198                     ypos = src.Height - wm.Height - 10;
199                     break;
200             }
201             return new Rectangle(xpos, ypos, wm.Width, wm.Height);
202         }
203 
204         /// <summary>
205         /// 添加文字水印:将原始图片添加文字水印之后存储
206         /// </summary>
207         /// <param name="srcPath">原图片绝对地址</param>
208         /// <param name="words">要添加的水印文本</param>
209         /// <param name="wp">水印位置WaterMarkPosition,参数可数</param>
210         /// <param name="fontSize">字体大小,可选</param>
211         /// <param name="myfont">字体myFont,可选</param>
212         public static Bitmap AddWaterMark_WORD(String srcPath, String words, WaterMarkPosition wp = WaterMarkPosition.BottomRight, int fontSize = 40, myFont myfont = myFont.楷体)
213         {
214 
215             using (Image src = Image.FromFile(srcPath))
216             {
217                 using (Bitmap bm = new Bitmap(srcPath))
218                 {
219                     using (Graphics g = Graphics.FromImage(bm))
220                     {
221                         //font定义特定的文字格式,包括文本字体,字号大小,和字形属性。
222                         Font crFont = new Font(myfont.ToString(), fontSize, FontStyle.Regular);
223                         //Sizef存储有序的浮点数对。通常为矩形的宽度和高度。(Drawing.SizeF)
224                         SizeF crSize = g.MeasureString(words, crFont);
225                         //FontAndSize fs = FontAndSize.GetValue(g, words, "arial", fontSize, src.Width);
226                         PointF p = getTextPoint(src, crSize, wp);
227                         StringFormat sf = getStringFormat();
228 
229                         drawText(g, words, crFont, p, sf);
230 
231                         return new Bitmap((Image)(bm.Clone()));
232                     }
233                 }
234             }
235 
236         }
237         /// <summary>
238         /// 绘制文本对象
239         /// </summary>
240         /// <param name="g">Graphics画面 对象</param>
241         /// <param name="wmText">水印文字的内容</param>
242         /// <param name="font">水印文字的字体</param>
243         /// <param name="p">水印文字的位置坐标有序对</param>
244         /// <param name="format">水印广本的格式化格式</param>
245         private static void drawText(Graphics g, String wmText, Font font, PointF p, StringFormat format)
246         {
247 
248             SolidBrush brush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
249             g.DrawString(wmText, font, brush, p, format);
250 
251             g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置g的呈现质量
252             //用指定的笔刷,和字体绘制文字
253             SolidBrush brush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
254             g.DrawString(wmText, font, brush2, new PointF(p.X + 1, p.Y + 1), format);
255   
256         }
257         /// <summary>
258         /// 取得水印的格式格式
259         /// </summary>
260         /// <returns>StringFormat格式</returns>
261         private static StringFormat getStringFormat()
262         {
263             StringFormat StrFormat = new StringFormat();
264             StrFormat.Alignment = StringAlignment.Center;
265             return StrFormat;
266         }
267         /// <summary>
268         /// 取水印文字的位置坐标有序对
269         /// </summary>
270         /// <param name="src">原Graphics图面 对象</param>
271         /// <param name="textSize">文字所占区域的宽度和高度有序对SizeF。</param>
272         /// <param name="wp">水印文字的位置WaterMarkPosition</param>
273         /// <returns></returns>
274         private static PointF getTextPoint(Image src, SizeF textSize, WaterMarkPosition wp)
275         {
276 
277             float x = 5;
278             float y = 5;
279 
280             int margin = 10;//水平方向,textSize文字居中对齐
281 
282             switch (wp)
283             {
284                 case WaterMarkPosition.TopLeft:
285                     x = textSize.Width/2+margin;
286                     y =  textSize.Height / 2 +5;
287                     break;
288                 case WaterMarkPosition.TopCenter:
289                     x = src.Width / 2;
290                     y =  textSize.Height / 2 + 5;
291                     break;
292                 case WaterMarkPosition.TopRight:
293                     x = src.Width  - textSize.Width/2- margin;
294                     y =  textSize.Height / 2+ 5;
295                     break;
296                 case WaterMarkPosition.BottomLeft:
297                     x =textSize.Width/2+ margin;
298                     y = src.Height- textSize.Height -5;
299                     break;
300                 case WaterMarkPosition.BottomCenter:
301                     x = src.Width / 2;
302                     y = src.Height - textSize.Height - 5;
303                     break;
304                 case WaterMarkPosition.BottomRight:
305                     x = src.Width - textSize.Width/2 - margin;
306                     y = src.Height - textSize.Height - 5;
307                     break; 
308             }
309             return new PointF(x, y);
310         }
311         /// <summary>
312         /// 将文本保存力图像格式的文件,备用作透明文字
313         /// </summary>
314         /// <param name="srcPath">原图片绝对地址,主要用来取得图像的大小,以便放文字</param>
315         /// <param name="wmText">文本(要转换为图像的文本)</param>
316         /// <param name="font">字体,new font("名称",大小),依赖操作系统</param>
317         public static void SaveWaterMarkWord_To_Picture(String srcPath,String wmText, Font font) 
318         {
319             using (Image src = Image.FromFile(srcPath))
320             {
321                 using (Bitmap bm = new Bitmap(srcPath))
322                 {
323                     using (Graphics g = Graphics.FromImage(bm))
324                     {
325                         // 生成水印图片(将文字写到图片中)
326                         SizeF crSize = g.MeasureString(wmText, font);
327                         Bitmap floatBmp = new Bitmap((int)crSize.Width + 3,
328                               (int)crSize.Height + 3, PixelFormat.Format32bppArgb);
329                         //GDI+绘图图面,封装一个绘图图面。
330                         Graphics fg = Graphics.FromImage(floatBmp);
331                         //浮点x和y坐标的有序对。PointF。
332                         PointF pt = new PointF(0, 0);
333 
334                         // 画阴影文字
335                         Brush TransparentBrush0 = new SolidBrush(Color.FromArgb(255, Color.Black));
336                         Brush TransparentBrush1 = new SolidBrush(Color.FromArgb(255, Color.Black));
337                         fg.DrawString(wmText, font, TransparentBrush0, pt.X, pt.Y + 1);
338                         fg.DrawString(wmText, font, TransparentBrush0, pt.X + 1, pt.Y);
339 
340                         fg.DrawString(wmText, font, TransparentBrush1, pt.X + 1, pt.Y + 1);
341                         fg.DrawString(wmText, font, TransparentBrush1, pt.X, pt.Y + 2);
342                         fg.DrawString(wmText, font, TransparentBrush1, pt.X + 2, pt.Y);
343 
344                         TransparentBrush0.Dispose();
345                         TransparentBrush1.Dispose();
346 
347                         //**画文字**//
348                         fg.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置fg的呈现质量
349                         //用指定的笔刷,和字体绘制文字
350                         StringFormat sf = getStringFormat();
351                         fg.DrawString(wmText, font, new SolidBrush(Color.White), pt.X, pt.Y, sf);
352 
353                         // 保存刚才的操作
354                         fg.Save();
355                         fg.Dispose();
356                         //保存图片对话取得路径和文件名
357                         SaveFileDialog savefileDlg1 = new SaveFileDialog();
358                         savefileDlg1.Filter = "(*.JPG)|*.JPG|(*.BMP)|*.BMP";
359                         savefileDlg1.FilterIndex = 0;
360                         savefileDlg1.Title = "保存文件";
361                         savefileDlg1.InitialDirectory = Application.StartupPath;
362                         savefileDlg1.RestoreDirectory = true;
363                         savefileDlg1.ShowDialog();
364                         string filename = savefileDlg1.FileName;
365                         if (filename == "") return;
366                         floatBmp.Save(filename);
367                     }
368                 }
369             }
370             
371         }
372     }
373   
374     #region ImageProceesClass
375     /// <summary>
376     /// 图像处理类:包含灰度化图像,自定义裁切,缩放,反转旋转等操作
377     /// </summary>
378     public class ImageProcees
379     {
380         #region 旋转翻转图像
381     
382         /// <summary>
383         /// 旋转翻转图像
384         /// </summary>
385         /// <param name="srcPicturePath">原图片绝对地址</param>
386         /// <param name="RotateFlipType">旋转或者翻转的枚举RotateFlipType</param>
387         /// <returns>返回bitmap对象</returns>
388         public static Bitmap RotateFlipPicture(String srcPicturePath, RotateFlipType RotateFlipType)
389         {
390             using (Image tmp = Image.FromFile(srcPicturePath))
391             {
392                 tmp.RotateFlip(RotateFlipType);
393                 return new Bitmap(tmp);
394             }   
395         }
396 
397        #endregion 旋转翻转图像
398 
399         #region 灰度化图像
400         
401        
402         /// <summary>
403        ///  (经典矩阵法)
404        /// </summary>
405        /// <param name="srcPicturePath">原图片绝对地址</param>
406        /// <returns>返回bitmap对象</returns>
407         public static Bitmap GrayPicuure(String srcPicturePath)
408         {
409             using (Bitmap currentBitmap = new Bitmap(srcPicturePath))
410             {
411                 using (Graphics g = Graphics.FromImage(currentBitmap))
412                 {
413                     using (ImageAttributes ia = new ImageAttributes())
414                     {       
415                         float[][] colorMatrix = {     
416                                             new   float[]   {0.299f,   0.299f,   0.299f,   0,   0},
417                                             new   float[]   {0.587f,   0.587f,   0.587f,   0,   0},
418                                             new   float[]   {0.114f,   0.114f,   0.114f,   0,   0},
419                                             new   float[]   {0,   0,   0,   1,   0},
420                                             new   float[]   {0,   0,   0,   0,   1}
421                                             };
422                         //颜色调整矩阵
423                         ColorMatrix cm = new ColorMatrix(colorMatrix);
424 
425                         ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
426 
427                         g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia);
428 
429                         return new Bitmap((Image)(currentBitmap.Clone()));
430                     }
431                 }
432             }
433         }
434         #endregion 灰度化图像
435         
436         #region 正方型裁剪并缩放
437 
438             /// <summary>
439             /// 正方型裁剪
440             /// 以图片中心为轴心,截取正方型,然后等比缩放
441             /// 用于头像处理
442             /// </summary>
443             /// <remarks>2012-12-18</remarks>
444             /// <param name="srcPicturePath">原图片绝对地址</param>
445             /// <param name="fileSaveUrl">缩略图存放绝对地址</param>
446             /// <param name="side">指定的边长(正方型)</param>
447             /// <param name="quality">质量(范围0-100)</param>
448             public static void CutBySquare(string srcPicturePath, string fileSaveUrl, int side, int quality)
449             {
450                 //创建目录
451                 //string dir = Path.GetDirectoryName(fileSaveUrl);
452                 //if (!Directory.Exists(dir))
453                 //    Directory.CreateDirectory(dir);
454 
455                 //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
456                 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath);
457 
458                 //原图宽高均小于模版,不作处理,直接保存
459                 if (initImage.Width <= side && initImage.Height <= side)
460                 {
461                     initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
462                 }
463                 else
464                 {
465                     //原始图片的宽、高
466                     int initWidth = initImage.Width;
467                     int initHeight = initImage.Height;
468 
469                     //非正方型先裁剪为正方型
470                     if (initWidth != initHeight)
471                     {
472                         //截图对象
473                         System.Drawing.Image pickedImage = null;
474                         System.Drawing.Graphics pickedG = null;
475 
476                         //宽大于高的横图
477                         if (initWidth > initHeight)
478                         {
479                             //对象实例化
480                             pickedImage = new System.Drawing.Bitmap(initHeight, initHeight);
481                             pickedG = System.Drawing.Graphics.FromImage(pickedImage);
482                             //设置质量
483                             pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
484                             pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
485                             //定位
486                             Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight);
487                             Rectangle toR = new Rectangle(0, 0, initHeight, initHeight);
488                             //画图
489                             pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
490                             //重置宽
491                             initWidth = initHeight;
492                         }
493                         //高大于宽的竖图
494                         else
495                         {
496                             //对象实例化
497                             pickedImage = new System.Drawing.Bitmap(initWidth, initWidth);
498                             pickedG = System.Drawing.Graphics.FromImage(pickedImage);
499                             //设置质量
500                             pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
501                             pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
502                             //定位
503                             Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth);
504                             Rectangle toR = new Rectangle(0, 0, initWidth, initWidth);
505                             //画图
506                             pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
507                             //重置高
508                             initHeight = initWidth;
509                         }
510 
511                         //将截图对象赋给原图
512                         initImage = (System.Drawing.Image)pickedImage.Clone();
513                         //释放截图资源
514                         pickedG.Dispose();
515                         pickedImage.Dispose();
516                     }
517 
518                     //缩略图对象
519                     System.Drawing.Image resultImage = new System.Drawing.Bitmap(side, side);
520                     System.Drawing.Graphics resultG = System.Drawing.Graphics.FromImage(resultImage);
521                     //设置质量
522                     resultG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
523                     resultG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
524                     //用指定背景色清空画布
525                     resultG.Clear(Color.White);
526                     //绘制缩略图
527                     resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel);
528 
529                     //关键质量控制
530                     //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
531                     ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
532                     ImageCodecInfo ici = null;
533                     foreach (ImageCodecInfo i in icis)
534                     {
535                         if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
536                         {
537                             ici = i;
538                         }
539                     }
540                     EncoderParameters ep = new EncoderParameters(1);
541                     ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);
542 
543                     //保存缩略图
544                     resultImage.Save(fileSaveUrl, ici, ep);
545 
546                     //释放关键质量控制所用资源
547                     ep.Dispose();
548 
549                     //释放缩略图资源
550                     resultG.Dispose();
551                     resultImage.Dispose();
552 
553                     //释放原始图片资源
554                     initImage.Dispose();
555                 }
556             }
557 
558             #endregion 正方型裁剪并缩放
559 
560             #region 自定义裁剪并缩放
561 
562             /// <summary>
563             /// 指定长宽裁剪
564             /// 按模版比例最大范围的裁剪图片并缩放至模版尺寸
565             /// </summary>
566             /// <remarks>2012-12-18</remarks>
567             /// <param name="srcPicturePath">原图片绝对地址</param>
568             /// <param name="fileSaveUrl">保存路径</param>
569             /// <param name="maxWidth">最大宽(单位:px)</param>
570             /// <param name="maxHeight">最大高(单位:px)</param>
571             /// <param name="quality">质量(范围0-100)</param>
572             public static void CutByCustom(string srcPicturePath, string fileSaveUrl, int maxWidth, int maxHeight, int quality)
573             {
574                 //从文件获取原始图片,并使用流中嵌入的颜色管理信息
575                 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath);
576 
577                 //原图宽高均小于模版,不作处理,直接保存
578                 if (initImage.Width <= maxWidth && initImage.Height <= maxHeight)
579                 {
580                     initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
581                 }
582                 else
583                 {
584                     //模版的宽高比例
585                     double templateRate = (double)maxWidth / maxHeight;
586                     //原图片的宽高比例
587                     double initRate = (double)initImage.Width / initImage.Height;
588 
589                     //原图与模版比例相等,直接缩放
590                     if (templateRate == initRate)
591                     {
592                         //按模版大小生成最终图片
593                         System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight);
594                         System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
595                         templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
596                         templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
597                         templateG.Clear(Color.White);
598                         templateG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);
599                         templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
600                     }
601                     //原图与模版比例不等,裁剪后缩放
602                     else
603                     {
604                         //裁剪对象
605                         System.Drawing.Image pickedImage = null;
606                         System.Drawing.Graphics pickedG = null;
607 
608                         //定位
609                         Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
610                         Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位
611 
612                         //宽为标准进行裁剪
613                         if (templateRate > initRate)
614                         {
615                             //裁剪对象实例化
616                             pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)System.Math.Floor(initImage.Width / templateRate));
617                             pickedG = System.Drawing.Graphics.FromImage(pickedImage);
618 
619                             //裁剪源定位
620                             fromR.X = 0;
621                             fromR.Y = (int)System.Math.Floor((initImage.Height - initImage.Width / templateRate) / 2);
622                             fromR.Width = initImage.Width;
623                             fromR.Height = (int)System.Math.Floor(initImage.Width / templateRate);
624 
625                             //裁剪目标定位
626                             toR.X = 0;
627                             toR.Y = 0;
628                             toR.Width = initImage.Width;
629                             toR.Height = (int)System.Math.Floor(initImage.Width / templateRate);
630                         }
631                         //高为标准进行裁剪
632                         else
633                         {
634                             pickedImage = new System.Drawing.Bitmap((int)System.Math.Floor(initImage.Height * templateRate), initImage.Height);
635                             pickedG = System.Drawing.Graphics.FromImage(pickedImage);
636 
637                             fromR.X = (int)System.Math.Floor((initImage.Width - initImage.Height * templateRate) / 2);
638                             fromR.Y = 0;
639                             fromR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
640                             fromR.Height = initImage.Height;
641 
642                             toR.X = 0;
643                             toR.Y = 0;
644                             toR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
645                             toR.Height = initImage.Height;
646                         }
647 
648                         //设置质量
649                         pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
650                         pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
651 
652                         //裁剪
653                         pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
654 
655                         //按模版大小生成最终图片
656                         System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight);
657                         System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
658                         templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
659                         templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
660                         templateG.Clear(Color.White);
661                         templateG.DrawImage(pickedImage, new System.Drawing.Rectangle(0, 0, maxWidth, maxHeight), new System.Drawing.Rectangle(0, 0, pickedImage.Width, pickedImage.Height), System.Drawing.GraphicsUnit.Pixel);
662 
663                         //关键质量控制
664                         //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
665                         ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
666                         ImageCodecInfo ici = null;
667                         foreach (ImageCodecInfo i in icis)
668                         {
669                             if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
670                             {
671                                 ici = i;
672                             }
673                         }
674                         EncoderParameters ep = new EncoderParameters(1);
675                         ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);
676 
677                         //保存缩略图
678                         templateImage.Save(fileSaveUrl, ici, ep);
679                         //templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
680 
681                         //释放资源
682                         templateG.Dispose();
683                         templateImage.Dispose();
684 
685                         pickedG.Dispose();
686                         pickedImage.Dispose();
687                     }
688                 }
689 
690                 //释放资源
691                 initImage.Dispose();
692             }
693             #endregion 自定义裁剪并缩放
694 
695             #region 等比缩放
696 
697             /// <summary>
698             /// 图片等比缩放
699             /// </summary>
700             /// <remarks> 2012-12-18</remarks>
701             /// <param name="srcPicturePath">原图片绝对地址</param>
702             /// <param name="savePath">另存为图片绝对地址</param>
703             /// <param name="targetWidth">指定的最大宽度</param>
704             /// <param name="targetHeight">指定的最大高度</param>
705             /// <param name="watermarkText">水印文字(为""表示不使用水印)</param>
706             /// <param name="watermarkImage">水印图片路径(为""表示不使用水印)</param>
707             public static void ZoomAuto(string srcPicturePath, string savePath, System.Double targetWidth, System.Double targetHeight, string watermarkText="", string watermarkImage="")
708             {
709                 //创建目录
710                 //string dir = Path.GetDirectoryName(savePath);
711                 //if (!Directory.Exists(dir))
712                 //    Directory.CreateDirectory(dir);
713 
714                 //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
715                 System.Drawing.Image initImage = System.Drawing.Image.FromFile(srcPicturePath);
716 
717                 //原图宽高均小于模版,不作处理,直接保存
718                 if (initImage.Width <= targetWidth && initImage.Height <= targetHeight)
719                 {
720                     //文字水印
721                     if (watermarkText != "")
722                     {
723                         using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(initImage))
724                         {
725                             System.Drawing.Font fontWater = new Font("黑体", 30);
726                             System.Drawing.Brush brushWater = new SolidBrush(Color.White);
727                             gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
728                             gWater.Dispose();
729                         }
730                     }
731 
732                     //透明图片水印
733                     if (watermarkImage != "")
734                     {
735                         if (File.Exists(watermarkImage))
736                         {
737                             //获取水印图片
738                             using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
739                             {
740                                 //水印绘制条件:原始图片宽高均大于或等于水印图片
741                                 if (initImage.Width >= wrImage.Width && initImage.Height >= wrImage.Height)
742                                 {
743                                     Graphics gWater = Graphics.FromImage(initImage);
744 
745                                     //透明属性
746                                     ImageAttributes imgAttributes = new ImageAttributes();
747                                     ColorMap colorMap = new ColorMap();
748                                     colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
749                                     colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
750                                     ColorMap[] remapTable = { colorMap };
751                                     imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
752 
753                                     float[][] colorMatrixElements = { 
754                                                                    new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
755                                                                    new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
756                                                                    new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
757                                                                    new float[] {0.0f,  0.0f,  0.0f,  0.3f, 0.0f},//透明度:0.3
758                                                                    new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
759                                                                    };
760 
761                                     ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
762                                     imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
763                                     gWater.DrawImage(wrImage, new Rectangle(initImage.Width - wrImage.Width, initImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);
764 
765                                     gWater.Dispose();
766                                 }
767                                 wrImage.Dispose();
768                             }
769                         }
770                     }
771 
772                     //保存
773                     initImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
774                 }
775                 else
776                 {
777                     //缩略图宽、高计算
778                     double newWidth = initImage.Width;
779                     double newHeight = initImage.Height;
780 
781                     //宽大于高或宽等于高(横图或正方)
782                     if (initImage.Width > initImage.Height || initImage.Width == initImage.Height)
783                     {
784                         //如果宽大于模版
785                         if (initImage.Width > targetWidth)
786                         {
787                             //宽按模版,高按比例缩放
788                             newWidth = targetWidth;
789                             newHeight = initImage.Height * (targetWidth / initImage.Width);
790                         }
791                     }
792                     //高大于宽(竖图)
793                     else
794                     {
795                         //如果高大于模版
796                         if (initImage.Height > targetHeight)
797                         {
798                             //高按模版,宽按比例缩放
799                             newHeight = targetHeight;
800                             newWidth = initImage.Width * (targetHeight / initImage.Height);
801                         }
802                     }
803 
804                     //生成新图
805                     //新建一个bmp图片
806                     System.Drawing.Image newImage = new System.Drawing.Bitmap((int)newWidth, (int)newHeight);
807                     //新建一个画板
808                     System.Drawing.Graphics newG = System.Drawing.Graphics.FromImage(newImage);
809 
810                     //设置质量
811                     newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
812                     newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
813 
814                     //置背景色
815                     newG.Clear(Color.White);
816                     //画图
817                     newG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, newImage.Width, newImage.Height), new System.Drawing.Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);
818 
819                     //文字水印
820                     if (watermarkText != "")
821                     {
822                         using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(newImage))
823                         {
824                             System.Drawing.Font fontWater = new Font("宋体", 30);
825                             System.Drawing.Brush brushWater = new SolidBrush(Color.White);
826                             gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
827                             gWater.Dispose();
828                         }
829                     }
830 
831                     //透明图片水印
832                     if (watermarkImage != "")
833                     {
834                         if (File.Exists(watermarkImage))
835                         {
836                             //获取水印图片
837                             using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
838                             {
839                                 //水印绘制条件:原始图片宽高均大于或等于水印图片
840                                 if (newImage.Width >= wrImage.Width && newImage.Height >= wrImage.Height)
841                                 {
842                                     Graphics gWater = Graphics.FromImage(newImage);
843 
844                                     //透明属性
845                                     ImageAttributes imgAttributes = new ImageAttributes();
846                                     ColorMap colorMap = new ColorMap();
847                                     colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
848                                     colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
849                                     ColorMap[] remapTable = { colorMap };
850                                     imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
851 
852                                     float[][] colorMatrixElements = { 
853                                    new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
854                                    new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
855                                    new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
856                                    new float[] {0.0f,  0.0f,  0.0f,  0.3f, 0.0f},//透明度:0.3
857                                    new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
858                                 };
859 
860                                     ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
861                                     imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
862                                     gWater.DrawImage(wrImage, new Rectangle(newImage.Width - wrImage.Width, newImage.Height - wrImage.Height, wrImage.Width, wrImage.Height), 0, 0, wrImage.Width, wrImage.Height, GraphicsUnit.Pixel, imgAttributes);
863                                     gWater.Dispose();
864                                 }
865                                 wrImage.Dispose();
866                             }
867                         }
868                     }
869 
870                     //保存缩略图
871                     newImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
872 
873                     //释放资源
874                     newG.Dispose();
875                     newImage.Dispose();
876                     initImage.Dispose();
877                 }
878             }
879 
880             #endregion
881 
882             #region 其它
883 
884             /// <summary>
885             /// 判断文件类型是否为WEB格式图片
886             /// (注:JPG,GIF,BMP,PNG)
887             /// </summary>
888             /// <param name="contentType">HttpPostedFile.ContentType</param>
889             /// <returns></returns>
890             public static bool IsWebImage(string contentType)
891             {
892                 if (contentType == "image/pjpeg" || contentType == "image/jpeg" || contentType == "image/gif" || contentType == "image/bmp" || contentType == "image/png")
893                 {
894                     return true;
895                 }
896                 else
897                 {
898                     return false;
899                 }
900             }
901 
902             #endregion 其它
903 
904       
905     }
906      #endregion
907 
908 }

 

posted @ 2012-12-30 15:22  thickThinker  阅读(783)  评论(0编辑  收藏  举报