C# 图片加水印、截取图片、压缩图片等。有个坑,往下看。当图片为jpg格式时,发现出来的图片结果异常的大

  1 /**
  2 *┌──────────────────────────────────────────────────────────────┐
  3 *│ 描   述:                                                    
  4 *│ 作   者:HLM                                              
  5 *│ 版   本:1.0                                                 
  6 *│ 创建时间:2021.7.8 13:06:33                             
  7 *└──────────────────────────────────────────────────────────────┘
  8 *┌──────────────────────────────────────────────────────────────┐
  9 *│ 命名空间: 图片剪切加水印                                   
 10 *│ 类   名:Image                                      
 11 *└──────────────────────────────────────────────────────────────┘
 12 */
 13 
 14 
 15 using System;
 16 using System.Collections.Generic;
 17 using System.Text;
 18 using System.IO;
 19 using System.Drawing;
 20 using System.Drawing.Drawing2D;
 21 using System.Drawing.Imaging;
 22 
 23 namespace 图片剪切加水印
 24 {
 25     public class Image
 26     {
 27         #region 正方型裁剪并缩放
 28 
 29         /// <summary>
 30         /// 正方型裁剪
 31         /// 以图片中心为轴心,截取正方型,然后等比缩放
 32         /// 用于头像处理
 33         /// </summary>
 34         /// <remarks>吴剑 2012-08-08</remarks>
 35         /// <param name="fromFile">原图Stream对象</param>
 36         /// <param name="fileSaveUrl">缩略图存放地址</param>
 37         /// <param name="side">指定的边长(正方型)</param>
 38         /// <param name="quality">质量(范围0-100)</param>
 39         public static void CutForSquare(System.IO.Stream fromFile, string fileSaveUrl, int side, int quality)
 40         {
 41             //创建目录
 42             string dir = Path.GetDirectoryName(fileSaveUrl);
 43             if (!Directory.Exists(dir))
 44                 Directory.CreateDirectory(dir);
 45 
 46             //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
 47             System.Drawing.Image initImage = System.Drawing.Image.FromStream(fromFile, true);
 48 
 49             //原图宽高均小于模版,不作处理,直接保存
 50             if (initImage.Width <= side && initImage.Height <= side)
 51             {
 52                 initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
 53             }
 54             else
 55             {
 56                 //原始图片的宽、高
 57                 int initWidth = initImage.Width;
 58                 int initHeight = initImage.Height;
 59 
 60                 //非正方型先裁剪为正方型
 61                 if (initWidth != initHeight)
 62                 {
 63                     //截图对象
 64                     System.Drawing.Image pickedImage = null;
 65                     System.Drawing.Graphics pickedG = null;
 66 
 67                     //宽大于高的横图
 68                     if (initWidth > initHeight)
 69                     {
 70                         //对象实例化
 71                         pickedImage = new System.Drawing.Bitmap(initHeight, initHeight);
 72                         pickedG = System.Drawing.Graphics.FromImage(pickedImage);
 73                         //设置质量
 74                         pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
 75                         pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 76                         //定位
 77                         Rectangle fromR = new Rectangle((initWidth - initHeight) / 2, 0, initHeight, initHeight);
 78                         Rectangle toR = new Rectangle(0, 0, initHeight, initHeight);
 79                         //画图
 80                         pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
 81                         //重置宽
 82                         initWidth = initHeight;
 83                     }
 84                     //高大于宽的竖图
 85                     else
 86                     {
 87                         //对象实例化
 88                         pickedImage = new System.Drawing.Bitmap(initWidth, initWidth);
 89                         pickedG = System.Drawing.Graphics.FromImage(pickedImage);
 90                         //设置质量
 91                         pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
 92                         pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
 93                         //定位
 94                         Rectangle fromR = new Rectangle(0, (initHeight - initWidth) / 2, initWidth, initWidth);
 95                         Rectangle toR = new Rectangle(0, 0, initWidth, initWidth);
 96                         //画图
 97                         pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
 98                         //重置高
 99                         initHeight = initWidth;
100                     }
101 
102                     //将截图对象赋给原图
103                     initImage = (System.Drawing.Image)pickedImage.Clone();
104                     //释放截图资源
105                     pickedG.Dispose();
106                     pickedImage.Dispose();
107                 }
108 
109                 //缩略图对象
110                 System.Drawing.Image resultImage = new System.Drawing.Bitmap(side, side);
111                 System.Drawing.Graphics resultG = System.Drawing.Graphics.FromImage(resultImage);
112                 //设置质量
113                 resultG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
114                 resultG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
115                 //用指定背景色清空画布
116                 resultG.Clear(Color.White);
117                 //绘制缩略图
118                 resultG.DrawImage(initImage, new System.Drawing.Rectangle(0, 0, side, side), new System.Drawing.Rectangle(0, 0, initWidth, initHeight), System.Drawing.GraphicsUnit.Pixel);
119 
120                 //关键质量控制
121                 //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
122                 ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
123                 ImageCodecInfo ici = null;
124                 foreach (ImageCodecInfo i in icis)
125                 {
126                     if (i.MimeType == "image/jpeg" || i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif")
127                     {
128                         ici = i;
129                     }
130                 }
131                 EncoderParameters ep = new EncoderParameters(1);
132                 ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)quality);
133 
134                 //保存缩略图
135                 resultImage.Save(fileSaveUrl, ici, ep);
136 
137                 //释放关键质量控制所用资源
138                 ep.Dispose();
139 
140                 //释放缩略图资源
141                 resultG.Dispose();
142                 resultImage.Dispose();
143 
144                 //释放原始图片资源
145                 initImage.Dispose();
146             }
147         }
148 
149         #endregion
150 
151         #region 自定义裁剪并缩放
152 
153         /// <summary>
154         /// 指定长宽裁剪
155         /// 按模版比例最大范围的裁剪图片并缩放至模版尺寸
156         /// </summary>
157         /// <remarks>吴剑 2012-08-08</remarks>
158         /// <param name="fromFile">原图Stream对象</param>
159         /// <param name="fileSaveUrl">保存路径</param>
160         /// <param name="maxWidth">最大宽(单位:px)</param>
161         /// <param name="maxHeight">最大高(单位:px)</param>
162         /// <param name="quality">质量(范围0-100)</param>
163         public static void CutForCustom(System.IO.Stream fromFile, string fileSaveUrl, int maxWidth, int quality, string watermarkText)
164         {
165             //从文件获取原始图片,并使用流中嵌入的颜色管理信息
166             System.Drawing.Image initImage = System.Drawing.Image.FromStream(fromFile, true);
167             int maxHeight = initImage.Height - 780;
168             //原图宽高均小于模版,不作处理,直接保存
169             if (initImage.Width <= maxWidth && initImage.Height <= maxHeight)
170             {
171                 initImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
172             }
173             else
174             {
175                 //模版的宽高比例
176                 double templateRate = (double)maxWidth / maxHeight;
177                 //原图片的宽高比例
178                 double initRate = (double)initImage.Width / initImage.Height;
179 
180                 //原图与模版比例相等,直接缩放
181                 if (templateRate == initRate)
182                 {
183                     //按模版大小生成最终图片
184                     System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight);
185                     System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
186                     templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
187                     templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
188                     templateG.Clear(Color.White);
189                     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);
190                     if (watermarkText != "")
191                     {
192                         using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(initImage))
193                         {
194                             System.Drawing.Font fontWater = new Font("黑体", 100);
195                             System.Drawing.Brush brushWater = new SolidBrush(Color.White);
196                             gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
197                             gWater.Dispose();
198                         }
199                     }
200                     templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
201                 }
202                 //原图与模版比例不等,裁剪后缩放
203                 else
204                 {
205                     //裁剪对象
206                     System.Drawing.Image pickedImage = null;
207                     System.Drawing.Graphics pickedG = null;
208 
209                     //定位
210                     Rectangle fromR = new Rectangle(0, 0, 0, 0);//原图裁剪定位
211                     Rectangle toR = new Rectangle(0, 0, 0, 0);//目标定位
212 
213                     //宽为标准进行裁剪
214                     if (templateRate > initRate)
215                     {
216                         //裁剪对象实例化
217                         pickedImage = new System.Drawing.Bitmap(initImage.Width, (int)System.Math.Floor(initImage.Width / templateRate));
218                         pickedG = System.Drawing.Graphics.FromImage(pickedImage);
219 
220                         //裁剪源定位
221                         fromR.X = 0;
222                         fromR.Y = (int)System.Math.Floor((initImage.Height - initImage.Width / templateRate) / 2);
223                         fromR.Width = initImage.Width;
224                         fromR.Height = (int)System.Math.Floor(initImage.Width / templateRate);
225 
226                         //裁剪目标定位
227                         toR.X = 0;
228                         toR.Y = 0;
229                         toR.Width = initImage.Width;
230                         toR.Height = (int)System.Math.Floor(initImage.Width / templateRate);
231                     }
232                     //高为标准进行裁剪
233                     else
234                     {
235                         pickedImage = new System.Drawing.Bitmap((int)System.Math.Floor(initImage.Height * templateRate), initImage.Height);
236                         pickedG = System.Drawing.Graphics.FromImage(pickedImage);
237 
238                         fromR.X = (int)System.Math.Floor((initImage.Width - initImage.Height * templateRate) / 2);
239                         fromR.Y = 0;
240                         fromR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
241                         fromR.Height = initImage.Height;
242 
243                         toR.X = 0;
244                         toR.Y = 0;
245                         toR.Width = (int)System.Math.Floor(initImage.Height * templateRate);
246                         toR.Height = initImage.Height;
247                     }
248 
249                     //设置质量
250                     pickedG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
251                     pickedG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
252 
253                     //裁剪
254                     pickedG.DrawImage(initImage, toR, fromR, System.Drawing.GraphicsUnit.Pixel);
255                     //按模版大小生成最终图片
256                     System.Drawing.Image templateImage = new System.Drawing.Bitmap(maxWidth, maxHeight);
257                     System.Drawing.Graphics templateG = System.Drawing.Graphics.FromImage(templateImage);
258                     templateG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
259                     templateG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
260                     templateG.Clear(Color.White);
261                     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);
262 
263                     //关键质量控制
264                     //获取系统编码类型数组,包含了jpeg,bmp,png,gif,tiff
265                     ImageCodecInfo[] icis = ImageCodecInfo.GetImageEncoders();
266                     ImageCodecInfo ici = null;
267                     foreach (ImageCodecInfo i in icis)
268                     {
269                         if (i.MimeType == "image/jpeg")
270                         {
271                             ici = i;
272                         }
273                         //else if (i.MimeType == "image/bmp")
274                         //{
275                         //    ici = i;
276                         //    return;
277                         //}
278                         //else if (i.MimeType == "image/png")
279                         //{
280                         //    ici = i;
281                         //    return;
282                         //}
283                         //else
284                         //{
285                         //    ici = i;
286                         //    return;
287                         //}
288                     }
289 
290                     EncoderParameters ep = new EncoderParameters(1);
291                     EncoderParameter myEncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 50L);
292                     ep.Param[0] = myEncoderParameter;
293                     if (watermarkText != "")
294                     {
295                         using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(templateImage))
296                         {
297                             System.Drawing.Font fontWater = new Font("黑体", 50);
298                             System.Drawing.Brush brushWater = new SolidBrush(Color.White);
299                             gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
300                             gWater.Dispose();
301                         }
302                     }
303                     //保存缩略图
304                     templateImage.Save(fileSaveUrl, ici, ep);
305                     //templateImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
306 
307                     //释放资源
308                     templateG.Dispose();
309                     templateImage.Dispose();
310 
311                     pickedG.Dispose();
312                     pickedImage.Dispose();
313                 }
314             }
315 
316             //释放资源
317             initImage.Dispose();
318         }
319         #endregion
320 
321         #region 等比缩放
322 
323         /// <summary>
324         /// 图片等比缩放
325         /// </summary>
326         /// <remarks>吴剑 2012-08-08</remarks>
327         /// <param name="fromFile">原图Stream对象</param>
328         /// <param name="savePath">缩略图存放地址</param>
329         /// <param name="targetWidth">指定的最大宽度</param>
330         /// <param name="targetHeight">指定的最大高度</param>
331         /// <param name="watermarkText">水印文字(为""表示不使用水印)</param>
332         /// <param name="watermarkImage">水印图片路径(为""表示不使用水印)</param>
333         public static void ZoomAuto(System.IO.Stream fromFile, string savePath, System.Double targetWidth, System.Double targetHeight, string watermarkText, string watermarkImage)
334         {
335             //创建目录
336             string dir = Path.GetDirectoryName(savePath);
337             if (!Directory.Exists(dir))
338                 Directory.CreateDirectory(dir);
339 
340             //原始图片(获取原始图片创建对象,并使用流中嵌入的颜色管理信息)
341             System.Drawing.Image initImage = System.Drawing.Image.FromStream(fromFile, true);
342 
343             //原图宽高均小于模版,不作处理,直接保存
344             if (initImage.Width <= targetWidth && initImage.Height <= targetHeight)
345             {
346                 //文字水印
347                 if (watermarkText != "")
348                 {
349                     using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(initImage))
350                     {
351                         System.Drawing.Font fontWater = new Font("黑体", 100);
352                         System.Drawing.Brush brushWater = new SolidBrush(Color.White);
353                         gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
354                         gWater.Dispose();
355                     }
356                 }
357 
358                 //透明图片水印
359                 if (watermarkImage != "")
360                 {
361                     if (File.Exists(watermarkImage))
362                     {
363                         //获取水印图片
364                         using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
365                         {
366                             //水印绘制条件:原始图片宽高均大于或等于水印图片
367                             if (initImage.Width >= wrImage.Width && initImage.Height >= wrImage.Height)
368                             {
369                                 Graphics gWater = Graphics.FromImage(initImage);
370 
371                                 //透明属性
372                                 ImageAttributes imgAttributes = new ImageAttributes();
373                                 ColorMap colorMap = new ColorMap();
374                                 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
375                                 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
376                                 ColorMap[] remapTable = { colorMap };
377                                 imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
378 
379                                 float[][] colorMatrixElements = {
380                                    new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
381                                    new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
382                                    new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
383                                    new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5
384                                    new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
385                                 };
386 
387                                 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
388                                 imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
389                                 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);
390 
391                                 gWater.Dispose();
392                             }
393                             wrImage.Dispose();
394                         }
395                     }
396                 }
397 
398                 //保存
399                 initImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
400             }
401             else
402             {
403                 //缩略图宽、高计算
404                 double newWidth = initImage.Width;
405                 double newHeight = initImage.Height;
406 
407                 //宽大于高或宽等于高(横图或正方)
408                 if (initImage.Width > initImage.Height || initImage.Width == initImage.Height)
409                 {
410                     //如果宽大于模版
411                     if (initImage.Width > targetWidth)
412                     {
413                         //宽按模版,高按比例缩放
414                         newWidth = targetWidth;
415                         newHeight = initImage.Height * (targetWidth / initImage.Width);
416                     }
417                 }
418                 //高大于宽(竖图)
419                 else
420                 {
421                     //如果高大于模版
422                     if (initImage.Height > targetHeight)
423                     {
424                         //高按模版,宽按比例缩放
425                         newHeight = targetHeight;
426                         newWidth = initImage.Width * (targetHeight / initImage.Height);
427                     }
428                 }
429 
430                 //生成新图
431                 //新建一个bmp图片
432                 System.Drawing.Image newImage = new System.Drawing.Bitmap((int)newWidth, (int)newHeight);
433                 //新建一个画板
434                 System.Drawing.Graphics newG = System.Drawing.Graphics.FromImage(newImage);
435 
436                 //设置质量
437                 newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
438                 newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
439 
440                 //置背景色
441                 newG.Clear(Color.White);
442                 //画图
443                 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);
444 
445                 //文字水印
446                 if (watermarkText != "")
447                 {
448                     using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(newImage))
449                     {
450                         System.Drawing.Font fontWater = new Font("宋体", 100);
451                         System.Drawing.Brush brushWater = new SolidBrush(Color.White);
452                         gWater.DrawString(watermarkText, fontWater, brushWater, 10, 10);
453                         gWater.Dispose();
454                     }
455                 }
456 
457                 //透明图片水印
458                 if (watermarkImage != "")
459                 {
460                     if (File.Exists(watermarkImage))
461                     {
462                         //获取水印图片
463                         using (System.Drawing.Image wrImage = System.Drawing.Image.FromFile(watermarkImage))
464                         {
465                             //水印绘制条件:原始图片宽高均大于或等于水印图片
466                             if (newImage.Width >= wrImage.Width && newImage.Height >= wrImage.Height)
467                             {
468                                 Graphics gWater = Graphics.FromImage(newImage);
469 
470                                 //透明属性
471                                 ImageAttributes imgAttributes = new ImageAttributes();
472                                 ColorMap colorMap = new ColorMap();
473                                 colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
474                                 colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
475                                 ColorMap[] remapTable = { colorMap };
476                                 imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);
477 
478                                 float[][] colorMatrixElements = {
479                                    new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
480                                    new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
481                                    new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
482                                    new float[] {0.0f,  0.0f,  0.0f,  0.5f, 0.0f},//透明度:0.5
483                                    new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
484                                 };
485 
486                                 ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
487                                 imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
488                                 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);
489                                 gWater.Dispose();
490                             }
491                             wrImage.Dispose();
492                         }
493                     }
494                 }
495 
496                 //保存缩略图
497                 newImage.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
498 
499                 //释放资源
500                 newG.Dispose();
501                 newImage.Dispose();
502                 initImage.Dispose();
503             }
504         }
505 
506         #endregion
507 
508         #region 其它
509 
510         /// <summary>
511         /// 判断文件类型是否为WEB格式图片
512         /// (注:JPG,GIF,BMP,PNG)
513         /// </summary>
514         /// <param name="contentType">HttpPostedFile.ContentType</param>
515         /// <returns></returns>
516         public static bool IsWebImage(string contentType)
517         {
518             if (contentType == "image/pjpeg" || contentType == "image/jpeg" || contentType == "image/gif" || contentType == "image/bmp" || contentType == "image/png")
519             {
520                 return true;
521             }
522             else
523             {
524                 return false;
525             }
526         }
527 
528         #endregion
529 
530 
531 
532     }
533 }

如何解决呢?:将126行中的

|| i.MimeType == "image/bmp" || i.MimeType == "image/png" || i.MimeType == "image/gif"删除掉即可设置压缩率

C# 图片加水印、截取图片、压缩图片等。有个坑,往下看。当图片为jpg格式时,发现出来的图片结果异常的大

上一篇:acwing 1020. 潜水员(背包求不少于问题)


下一篇:Center OS 7 通过Docker部署yapi