diff --git a/Apewer.Windows/Apewer.Windows.csproj b/Apewer.Windows/Apewer.Windows.csproj
index 02d7562..bd46bb5 100644
--- a/Apewer.Windows/Apewer.Windows.csproj
+++ b/Apewer.Windows/Apewer.Windows.csproj
@@ -1,64 +1,66 @@
-
+
-
- CS0108;CS0612
- net461;net40;net20;netcoreapp3.1
-
+
+ CS0108;CS0612
+ net461;net40;net20;netcoreapp3.1
+
-
-
- 实现 Windows 程序功能。
-
+
+
+ 实现 Windows 程序功能。
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ DRAWING;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Apewer/Apewer.csproj b/Apewer/Apewer.csproj
index 8f32c8d..77ca79c 100644
--- a/Apewer/Apewer.csproj
+++ b/Apewer/Apewer.csproj
@@ -1,53 +1,53 @@
-
-
-
- true
- 实现通用的实用功能。
- netstandard2.0;netcoreapp3.1;net461;net40;net20
-
-
-
-
- NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
-
-
-
-
- NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
-
-
-
-
- NETFX;NET20;$(DefineConstants);$(AdditionalConstants)
-
-
-
-
-
-
-
-
- NETFX;NET40;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
-
-
-
-
-
-
-
-
- NETFX;NET461;NET45;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
-
-
-
-
-
-
-
-
- HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
-
+
+
+
+ true
+ 实现通用的实用功能。
+ netstandard2.0;netcoreapp3.1;net461;net40;net20
+
+
+
+
+ NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+ NETSTD;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+ NETFX;NET20;DRAWING;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+
+
+
+
+ NETFX;NET40;DRAWING;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+
+
+
+
+ NETFX;NET461;NET45;DRAWING;HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
+
+
+
+
+
+
+
+
+ HAVE_ASYNC;HAVE_BIG_INTEGER;$(DefineConstants);$(AdditionalConstants)
+
diff --git a/Apewer/DrawingUtility.cs b/Apewer/DrawingUtility.cs
new file mode 100644
index 0000000..79d6b99
--- /dev/null
+++ b/Apewer/DrawingUtility.cs
@@ -0,0 +1,123 @@
+#if DRAWING
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.IO;
+
+namespace Apewer
+{
+
+ /// 绘图。
+ public static class DrawingUtility
+ {
+
+ /// 优化 Graphics 对象的属性,提升绘图质量。
+ public static Graphics Optimize(this Graphics graphics)
+ {
+ if (graphics != null)
+ {
+ graphics.CompositingMode = CompositingMode.SourceOver;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+ graphics.SmoothingMode = SmoothingMode.AntiAlias;
+ }
+ return graphics;
+ }
+
+ /// 保存图像为文件。
+ ///
+ public static byte[] Save(this Image image, ImageFormat format)
+ {
+ if (image == null) throw new ArgumentNullException(nameof(image));
+ if (format == null) throw new ArgumentNullException(nameof(format));
+
+ using (var memory = new MemoryStream())
+ {
+ image.Save(memory, format);
+ return memory.ToArray();
+ }
+ }
+
+ /// 保存为 JPEG 文件。
+ /// Image 实例。
+ /// JPEG 质量,0 为最低质量,100 为最高质量。
+ ///
+ ///
+ ///
+ public static byte[] SaveAsJpeg(this Image image, int quality = 100)
+ {
+ if (image == null) throw new ArgumentNullException(nameof(image));
+ if (quality < 0 || quality > 100) throw new ArgumentOutOfRangeException(nameof(quality));
+
+ var codec = ImageCodecInfo.GetImageDecoders().Find(x => x.FormatID == ImageFormat.Jpeg.Guid);
+ if (codec == null) throw new System.Runtime.InteropServices.ExternalException($"系统中不存在 JPEG 编码器。");
+
+ var parameters = new EncoderParameters(1);
+ parameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
+
+ using (var memory = new MemoryStream())
+ {
+ image.Save(memory, codec, parameters);
+ return memory.ToArray();
+ }
+ }
+
+ /// 缩放图像,生成新图像。
+ /// 原始图像。
+ /// 新图像的大小。
+ /// 填充新图像背景色。
+ ///
+ ///
+ public static Bitmap Scale(this Image image, Size size, Color? backgroundColor = null) => Scale(image, size.Width, size.Height, backgroundColor);
+
+ /// 缩放图像,生成新图像。
+ /// 原始图像。
+ /// 新图像的宽度。
+ /// 新图像的高度。
+ /// 填充新图像背景色。
+ ///
+ ///
+ static Bitmap Scale(this Image image, int width, int height, Color? backgroundColor = null)
+ {
+ if (image == null) throw new ArgumentNullException(nameof(image));
+ if (width < 1) throw new ArgumentOutOfRangeException(nameof(width));
+ if (height < 1) throw new ArgumentOutOfRangeException(nameof(height));
+
+ // 检查原始图像是否为透明格式
+ var rawFormat = image.RawFormat;
+ var isTransparentFormat = rawFormat.Equals(ImageFormat.Png) || rawFormat.Equals(ImageFormat.Gif);
+ var pixelFormat = isTransparentFormat ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb;
+
+ var bitmap = new Bitmap(width, height, pixelFormat);
+ try
+ {
+ using (var graphic = Graphics.FromImage(bitmap))
+ {
+ graphic.CompositingMode = CompositingMode.SourceOver;
+ graphic.CompositingQuality = CompositingQuality.HighQuality;
+ graphic.SmoothingMode = SmoothingMode.AntiAlias;
+
+ // 填充背景色
+ if (isTransparentFormat)
+ {
+ if (backgroundColor != null && backgroundColor.HasValue) graphic.Clear(backgroundColor.Value);
+ }
+
+ // 绘制新图像
+ graphic.DrawImage(image, 0, 0, width, height);
+ }
+ return bitmap;
+ }
+ catch
+ {
+ bitmap.Dispose();
+ throw;
+ }
+ }
+
+ }
+
+}
+
+#endif