You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
5.0 KiB

  1. #if DRAWING
  2. using System;
  3. using System.Drawing;
  4. using System.Drawing.Drawing2D;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. namespace Apewer
  8. {
  9. /// <summary>绘图。</summary>
  10. public static class DrawingUtility
  11. {
  12. /// <summary>优化 Graphics 对象的属性,提升绘图质量。</summary>
  13. public static Graphics Optimize(this Graphics graphics)
  14. {
  15. if (graphics != null)
  16. {
  17. graphics.CompositingMode = CompositingMode.SourceOver;
  18. graphics.CompositingQuality = CompositingQuality.HighQuality;
  19. graphics.SmoothingMode = SmoothingMode.AntiAlias;
  20. }
  21. return graphics;
  22. }
  23. /// <summary>保存图像为文件。</summary>
  24. /// <exception cref="ArgumentNullException"></exception>
  25. public static byte[] Save(this Image image, ImageFormat format)
  26. {
  27. if (image == null) throw new ArgumentNullException(nameof(image));
  28. if (format == null) throw new ArgumentNullException(nameof(format));
  29. using (var memory = new MemoryStream())
  30. {
  31. image.Save(memory, format);
  32. return memory.ToArray();
  33. }
  34. }
  35. /// <summary>保存为 JPEG 文件。</summary>
  36. /// <param name="image">Image 实例。</param>
  37. /// <param name="quality">JPEG 质量,0 为最低质量,100 为最高质量。</param>
  38. /// <exception cref="ArgumentNullException" />
  39. /// <exception cref="ArgumentOutOfRangeException" />
  40. /// <exception cref="System.Runtime.InteropServices.ExternalException" />
  41. public static byte[] SaveAsJpeg(this Image image, int quality = 100)
  42. {
  43. if (image == null) throw new ArgumentNullException(nameof(image));
  44. if (quality < 0 || quality > 100) throw new ArgumentOutOfRangeException(nameof(quality));
  45. var codec = ImageCodecInfo.GetImageDecoders().Find(x => x.FormatID == ImageFormat.Jpeg.Guid);
  46. if (codec == null) throw new System.Runtime.InteropServices.ExternalException($"系统中不存在 JPEG 编码器。");
  47. var parameters = new EncoderParameters(1);
  48. parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
  49. using (var memory = new MemoryStream())
  50. {
  51. image.Save(memory, codec, parameters);
  52. return memory.ToArray();
  53. }
  54. }
  55. /// <summary>缩放图像,生成新图像。</summary>
  56. /// <param name="image">原始图像。</param>
  57. /// <param name="size">新图像的大小。</param>
  58. /// <param name="backgroundColor">填充新图像背景色。</param>
  59. /// <exception cref="ArgumentNullException"></exception>
  60. /// <exception cref="ArgumentOutOfRangeException"></exception>
  61. public static Bitmap Scale(this Image image, Size size, Color? backgroundColor = null) => Scale(image, size.Width, size.Height, backgroundColor);
  62. /// <summary>缩放图像,生成新图像。</summary>
  63. /// <param name="image">原始图像。</param>
  64. /// <param name="width">新图像的宽度。</param>
  65. /// <param name="height">新图像的高度。</param>
  66. /// <param name="backgroundColor">填充新图像背景色。</param>
  67. /// <exception cref="ArgumentNullException"></exception>
  68. /// <exception cref="ArgumentOutOfRangeException"></exception>
  69. static Bitmap Scale(this Image image, int width, int height, Color? backgroundColor = null)
  70. {
  71. if (image == null) throw new ArgumentNullException(nameof(image));
  72. if (width < 1) throw new ArgumentOutOfRangeException(nameof(width));
  73. if (height < 1) throw new ArgumentOutOfRangeException(nameof(height));
  74. // 检查原始图像是否为透明格式
  75. var rawFormat = image.RawFormat;
  76. var isTransparentFormat = rawFormat.Equals(ImageFormat.Png) || rawFormat.Equals(ImageFormat.Gif);
  77. var pixelFormat = isTransparentFormat ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb;
  78. var bitmap = new Bitmap(width, height, pixelFormat);
  79. try
  80. {
  81. using (var graphic = Graphics.FromImage(bitmap))
  82. {
  83. graphic.CompositingMode = CompositingMode.SourceOver;
  84. graphic.CompositingQuality = CompositingQuality.HighQuality;
  85. graphic.SmoothingMode = SmoothingMode.AntiAlias;
  86. // 填充背景色
  87. if (isTransparentFormat)
  88. {
  89. if (backgroundColor != null && backgroundColor.HasValue) graphic.Clear(backgroundColor.Value);
  90. }
  91. // 绘制新图像
  92. graphic.DrawImage(image, 0, 0, width, height);
  93. }
  94. return bitmap;
  95. }
  96. catch
  97. {
  98. bitmap.Dispose();
  99. throw;
  100. }
  101. }
  102. }
  103. }
  104. #endif