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"删除掉即可设置压缩率