1.3 实现图片压缩、添加文字或图片水印、指定位置裁剪等功能的ImageUtility(内有效果图) (转)

在web程序开发中,相信很多同行们都碰到过图片压缩,生成缩略图的操作,比如产品的图片,会员的照片等等功能。

为了满足此类操作今天给大家介绍ImageUtility类,该类几乎实现了常规网站开发图片处理的功能,比如按大小生成缩略图,指定位置和大小裁剪,以前给图片添加 文字或图片水印等。此外此类生成的文件格式均为.jpg格式,如果想要.GIF或PNG的透明效果的朋友,就不要再向下看了。

老样子,先上图:

http://www.cnblogs.com/loskiv

所有详细的介绍在代里的注释里已经标识的很清楚了,在此不在多说。

代码:


  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Drawing;
  5using System.Drawing.Drawing2D;
  6using System.Drawing.Imaging;
  7using System.IO;
  8
  9namespace Loskiv.Utility
 10{
 11    /// <summary>
 12    /// 名称:图片处理常用操作类
 13    /// 作者:loskiv
 14    /// 创建时间:2009-07-07
 15    /// </summary>

 16    public class ImageUtility
 17    {
 18
 19        /// <summary>
 20        /// 获取指定mimeType的ImageCodecInfo
 21        /// </summary>

 22        private static ImageCodecInfo GetImageCodecInfo(string mimeType)
 23        {
 24            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
 25            foreach (ImageCodecInfo ici in CodecInfo)
 26            {
 27                if (ici.MimeType == mimeType) return ici;
 28            }

 29            return null;
 30        }

 31
 32        /// <summary>
 33        ///  获取inputStream中的Bitmap对象
 34        /// </summary>

 35        public static Bitmap GetBitmapFromStream(Stream inputStream)
 36        {
 37            Bitmap bitmap = new Bitmap(inputStream);
 38            return bitmap;
 39        }

 40
 41        /// <summary>
 42        /// 将Bitmap对象压缩为JPG图片类型
 43        /// </summary>
 44        /// </summary>
 45        /// <param name="bmp">源bitmap对象</param>
 46        /// <param name="saveFilePath">目标图片的存储地址</param>
 47        /// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>

 48        public static void CompressAsJPG(Bitmap bmp, string saveFilePath, int quality)
 49        {
 50            EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); ;
 51            EncoderParameters ps = new EncoderParameters(1);
 52            ps.Param[0= p;
 53            bmp.Save(saveFilePath, GetImageCodecInfo("image/jpeg"), ps);
 54            bmp.Dispose();
 55        }

 56
 57        /// <summary>
 58        /// 将inputStream中的对象压缩为JPG图片类型
 59        /// </summary>
 60        /// <param name="inputStream">源Stream对象</param>
 61        /// <param name="saveFilePath">目标图片的存储地址</param>
 62        /// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>

 63        public static void CompressAsJPG(Stream inputStream, string saveFilePath, int quality)
 64        {
 65            Bitmap bmp = GetBitmapFromStream(inputStream);
 66            CompressAsJPG(bmp, saveFilePath, quality);
 67        }

 68
 69
 70        /// <summary>
 71        /// 生成缩略图(JPG 格式)
 72        /// </summary>
 73        /// <param name="inputStream">包含图片的Stream</param>
 74        /// <param name="saveFilePath">目标图片的存储地址</param>
 75        /// <param name="width">缩略图的宽</param>
 76        /// <param name="height">缩略图的高</param>

 77        public static void ThumbAsJPG(Stream inputStream, string saveFilePath, int width, int height)
 78        {
 79            Image image = Image.FromStream(inputStream);
 80            if (image.Width == width && image.Height == height)
 81            {
 82                CompressAsJPG(inputStream, saveFilePath, 80);
 83            }

 84            int tWidth, tHeight, tLeft, tTop;
 85            double fScale = (double)height / (double)width;
 86            if (((double)image.Width * fScale) > (double)image.Height)
 87            {
 88                tWidth = width;
 89                tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);
 90                tLeft = 0;
 91                tTop = (height - tHeight) / 2;
 92            }

 93            else
 94            {
 95                tHeight = height;
 96                tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);
 97                tLeft = (width - tWidth) / 2;
 98                tTop = 0;
 99            }

100            if (tLeft < 0) tLeft = 0;
101            if (tTop < 0) tTop = 0;
102
103            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
104            Graphics graphics = Graphics.FromImage(bitmap);
105
106            //可以在这里设置填充背景颜色
107            graphics.Clear(Color.White);
108            graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));
109            image.Dispose();
110            try
111            {
112                CompressAsJPG(bitmap, saveFilePath, 80);
113            }

114            catch
115            {
116                ;
117            }

118            finally
119            {
120                bitmap.Dispose();
121                graphics.Dispose();
122            }

123        }

124
125        /// <summary>
126        /// 将Bitmap对象裁剪为指定JPG文件
127        /// </summary>
128        /// <param name="bmp">源bmp对象</param>
129        /// <param name="saveFilePath">目标图片的存储地址</param>
130        /// <param name="x">开始坐标x,单位:像素</param>
131        /// <param name="y">开始坐标y,单位:像素</param>
132        /// <param name="width">宽度:像素</param>
133        /// <param name="height">高度:像素</param>

134        public static void CutAsJPG(Bitmap bmp, string saveFilePath, int x, int y, int width, int height)
135        {
136            int bmpW = bmp.Width;
137            int bmpH = bmp.Height;
138
139            if (x >= bmpW || y >= bmpH)
140            {
141                CompressAsJPG(bmp, saveFilePath, 80);
142                return;
143            }

144
145            if (x + width > bmpW)
146            {
147                width = bmpW - x;
148            }

149
150            if (y + height > bmpH)
151            {
152                height = bmpH - y;
153            }

154
155            Bitmap bmpOut = new Bitmap(width, height, PixelFormat.Format24bppRgb);
156            Graphics g = Graphics.FromImage(bmpOut);
157            g.DrawImage(bmp, new Rectangle(00, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
158            g.Dispose();
159            bmp.Dispose();
160            CompressAsJPG(bmpOut, saveFilePath, 80);
161        }

162
163        /// <summary>
164        /// 将Stream中的对象裁剪为指定JPG文件
165        /// </summary>
166        /// <param name="inputStream">源bmp对象</param>
167        /// <param name="saveFilePath">目标图片的存储地址</param>
168        /// <param name="x">开始坐标x,单位:像素</param>
169        /// <param name="y">开始坐标y,单位:像素</param>
170        /// <param name="width">宽度:像素</param>
171        /// <param name="height">高度:像素</param>

172        public static void CutAsJPG(Stream inputStream, string saveFilePath, int x, int y, int width, int height)
173        {
174            Bitmap bmp = GetBitmapFromStream(inputStream);
175            CutAsJPG(bmp, saveFilePath, x, y, width, height);
176        }

177
178
179        #region 图片水印操作
180
181        /// <summary>
182        /// 给图片添加图片水印
183        /// </summary>
184        /// <param name="inputStream">包含要源图片的流</param>
185        /// <param name="watermarkPath">水印图片的物理地址</param>
186        /// <param name="saveFilePath">目标图片的存储地址</param>
187        /// <param name="mp">水印位置</param>

188        public static void AddPicWatermarkAsJPG(Stream inputStream, string watermarkPath, string saveFilePath, MarkPosition mp)
189        {
190
191            Image image = Image.FromStream(inputStream);
192            Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
193            Graphics g = Graphics.FromImage(b);
194            g.Clear(Color.White);
195            g.SmoothingMode = SmoothingMode.HighQuality;
196            g.InterpolationMode = InterpolationMode.High;
197            g.DrawImage(image, 00, image.Width, image.Height);
198
199            AddWatermarkImage(g, watermarkPath, mp, image.Width, image.Height);
200
201            try
202            {
203                CompressAsJPG(b, saveFilePath, 80);
204            }

205            catch { ;}
206            finally
207            {
208                b.Dispose();
209                image.Dispose();
210            }

211        }

212
213
214        /// <summary>
215        /// 给图片添加图片水印
216        /// </summary>
217        /// <param name="sourcePath">源图片的存储地址</param>
218        /// <param name="watermarkPath">水印图片的物理地址</param>
219        /// <param name="saveFilePath">目标图片的存储地址</param>
220        /// <param name="mp">水印位置</param>

221        public static void AddPicWatermarkAsJPG(string sourcePath, string watermarkPath, string saveFilePath, MarkPosition mp)
222        {
223            if (File.Exists(sourcePath))
224            {
225                using (StreamReader sr = new StreamReader(sourcePath))
226                {
227                    AddPicWatermarkAsJPG(sr.BaseStream, watermarkPath, saveFilePath, mp);
228                }

229            }

230        }

231        /// <summary>
232        /// 给图片添加文字水印
233        /// </summary>
234        /// <param name="inputStream">包含要源图片的流</param>
235        /// <param name="text">水印文字</param>
236        /// <param name="saveFilePath">目标图片的存储地址</param>
237        /// <param name="mp">水印位置</param>

238        public static void AddTextWatermarkAsJPG(Stream inputStream, string text, string saveFilePath, MarkPosition mp)
239        {
240
241            Image image = Image.FromStream(inputStream);
242            Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
243            Graphics g = Graphics.FromImage(b);
244            g.Clear(Color.White);
245            g.SmoothingMode = SmoothingMode.HighQuality;
246            g.InterpolationMode = InterpolationMode.High;
247            g.DrawImage(image, 00, image.Width, image.Height);
248
249            AddWatermarkText(g, text, mp, image.Width, image.Height);
250
251            try
252            {
253                CompressAsJPG(b, saveFilePath, 80);
254            }

255            catch { ;}
256            finally
257            {
258                b.Dispose();
259                image.Dispose();
260            }

261        }

262
263        /// <summary>
264        /// 给图片添加文字水印
265        /// </summary>
266        /// <param name="sourcePath">源图片的存储地址</param>
267        /// <param name="text">水印文字</param>
268        /// <param name="saveFilePath">目标图片的存储地址</param>
269        /// <param name="mp">水印位置</param>

270        public static void AddTextWatermarkAsJPG(string sourcePath, string text, string saveFilePath, MarkPosition mp)
271        {
272            if (File.Exists(sourcePath))
273            {
274                using (StreamReader sr = new StreamReader(sourcePath))
275                {
276                    AddTextWatermarkAsJPG(sr.BaseStream, text, saveFilePath, mp);
277                }

278            }

279        }

280
281        /// <summary>
282        /// 添加文字水印
283        /// </summary>
284        /// <param name="picture">要加水印的原图像</param>
285        /// <param name="text">水印文字</param>
286        /// <param name="mp">添加的位置</param>
287        /// <param name="width">原图像的宽度</param>
288        /// <param name="height">原图像的高度</param>

289        private static void AddWatermarkText(Graphics picture, string text, MarkPosition mp, int width, int height)
290        {
291            int[] sizes = new int[] 16141210864 };
292            Font crFont = null;
293            SizeF crSize = new SizeF();
294            for (int i = 0; i < 7; i++)
295            {
296                crFont = new Font("Arial", sizes[i], FontStyle.Bold);
297                crSize = picture.MeasureString(text, crFont);
298
299                if ((ushort)crSize.Width < (ushort)width)
300                    break;
301            }

302
303            float xpos = 0;
304            float ypos = 0;
305
306            switch (mp)
307            {
308                case MarkPosition.MP_Left_Top:
309                    xpos = ((float)width * (float).01+ (crSize.Width / 2);
310                    ypos = (float)height * (float).01;
311                    break;
312                case MarkPosition.MP_Right_Top:
313                    xpos = ((float)width * (float).99- (crSize.Width / 2);
314                    ypos = (float)height * (float).01;
315                    break;
316                case MarkPosition.MP_Right_Bottom:
317                    xpos = ((float)width * (float).99- (crSize.Width / 2);
318                    ypos = ((float)height * (float).99- crSize.Height;
319                    break;
320                case MarkPosition.MP_Left_Bottom:
321                    xpos = ((float)width * (float).01+ (crSize.Width / 2);
322                    ypos = ((float)height * (float).99- crSize.Height;
323                    break;
324            }

325
326            StringFormat StrFormat = new StringFormat();
327            StrFormat.Alignment = StringAlignment.Center;
328
329            SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153000));
330            picture.DrawString(text, crFont, semiTransBrush2, xpos + 1, ypos + 1, StrFormat);
331
332            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153255255255));
333            picture.DrawString(text, crFont, semiTransBrush, xpos, ypos, StrFormat);
334
335            semiTransBrush2.Dispose();
336            semiTransBrush.Dispose();
337
338        }

339
340        /// <summary>
341        /// 添加图片水印
342        /// </summary>
343        /// <param name="picture">要加水印的原图像</param>
344        /// <param name="waterMarkPath">水印文件的物理地址</param>
345        /// <param name="mp">添加的位置</param>
346        /// <param name="width">原图像的宽度</param>
347        /// <param name="height">原图像的高度</param>

348        private static void AddWatermarkImage(Graphics picture, string waterMarkPath, MarkPosition mp, int width, int height)
349        {
350            Image watermark = new Bitmap(waterMarkPath);
351
352            ImageAttributes imageAttributes = new ImageAttributes();
353            ColorMap colorMap = new ColorMap();
354
355            colorMap.OldColor = Color.FromArgb(25502550);
356            colorMap.NewColor = Color.FromArgb(0000);
357            ColorMap[] remapTable = { colorMap };
358
359            imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
360
361            float[][] colorMatrixElements = {
362                                                 new float[] {1.0f,  0.0f,  0.0f,  0.0f0.0f},
363                                                 new float[] {0.0f,  1.0f,  0.0f,  0.0f0.0f},
364                                                 new float[] {0.0f,  0.0f,  1.0f,  0.0f0.0f},
365                                                 new float[] {0.0f,  0.0f,  0.0f,  0.3f0.0f},
366                                                 new float[] {0.0f,  0.0f,  0.0f,  0.0f1.0f}
367                                             }
;
368
369            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);
370
371            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
372
373            int xpos = 0;
374            int ypos = 0;
375            int WatermarkWidth = 0;
376            int WatermarkHeight = 0;
377            double bl = 1d;
378            if ((width > watermark.Width * 4&& (height > watermark.Height * 4))
379            {
380                bl = 1;
381            }

382            else if ((width > watermark.Width * 4&& (height < watermark.Height * 4))
383            {
384                bl = Convert.ToDouble(height / 4/ Convert.ToDouble(watermark.Height);
385
386            }

387            else
388
389                if ((width < watermark.Width * 4&& (height > watermark.Height * 4))
390                {
391                    bl = Convert.ToDouble(width / 4/ Convert.ToDouble(watermark.Width);
392                }

393                else
394                {
395                    if ((width * watermark.Height) > (height * watermark.Width))
396                    {
397                        bl = Convert.ToDouble(height / 4/ Convert.ToDouble(watermark.Height);
398
399                    }

400                    else
401                    {
402                        bl = Convert.ToDouble(width / 4/ Convert.ToDouble(watermark.Width);
403
404                    }

405
406                }

407
408            WatermarkWidth = Convert.ToInt32(watermark.Width * bl);
409            WatermarkHeight = Convert.ToInt32(watermark.Height * bl);
410
411
412            switch (mp)
413            {
414                case MarkPosition.MP_Left_Top:
415                    xpos = 10;
416                    ypos = 10;
417                    break;
418                case MarkPosition.MP_Right_Top:
419                    xpos = width - WatermarkWidth - 10;
420                    ypos = 10;
421                    break;
422                case MarkPosition.MP_Right_Bottom:
423                    xpos = width - WatermarkWidth - 10;
424                    ypos = height - WatermarkHeight - 10;
425                    break;
426                case MarkPosition.MP_Left_Bottom:
427                    xpos = 10;
428                    ypos = height - WatermarkHeight - 10;
429                    break;
430            }

431
432            picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 00, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
433
434
435            watermark.Dispose();
436            imageAttributes.Dispose();
437        }

438
439        /// <summary>
440        /// 水印的位置
441        /// </summary>

442        public enum MarkPosition
443        {
444            /// <summary>
445            /// 左上角
446            /// </summary>

447            MP_Left_Top,
448
449            /// <summary>
450            /// 左下角
451            /// </summary>

452            MP_Left_Bottom,
453
454            /// <summary>
455            /// 右上角
456            /// </summary>

457            MP_Right_Top,
458
459            /// <summary>
460            /// 右下角
461            /// </summary>

462            MP_Right_Bottom
463        }

464
465
466        #endregion

467
468    }

469}

470


posted @ 2009-07-31 16:30  awp110  阅读(454)  评论(0编辑  收藏  举报