From e984bb9dc124f1ca572c652236969b771b751069 Mon Sep 17 00:00:00 2001 From: Elivo Date: Mon, 6 Apr 2026 17:18:36 +0800 Subject: [PATCH] =?UTF-8?q?DrawingUtility=20=E5=A2=9E=E5=8A=A0=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=9B=BE=E5=83=8F=E6=97=8B=E8=BD=AC=E7=9A=84=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=A2=9E=E5=8A=A0=E7=AD=89=E6=AF=94=E4=BE=8B?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E7=9A=84=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Apewer/DrawingUtility.cs | 99 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/Apewer/DrawingUtility.cs b/Apewer/DrawingUtility.cs index 79d6b99..ecb62a4 100644 --- a/Apewer/DrawingUtility.cs +++ b/Apewer/DrawingUtility.cs @@ -25,6 +25,72 @@ namespace Apewer return graphics; } + /// 识别图像的旋转角度并进行调整。 + /// + public static void AdjustRotation(this Image image) + { + if (image == null) throw new ArgumentNullException(nameof(image)); + + // 检测旋转角度 + var angle = 0; + if (Array.IndexOf(image.PropertyIdList, 274) > -1) + { + var property = image.GetPropertyItem(274); + var value = property.Value[0]; + switch (value) + { + case 1: break; + case 3: angle = 180; break; + case 6: angle = 90; break; + case 8: angle = 270; break; + } + } + + // 自适应旋转 + switch (angle) + { + case 90: image.RotateFlip(RotateFlipType.Rotate90FlipNone); break; + case 180: image.RotateFlip(RotateFlipType.Rotate180FlipNone); break; + case 270: image.RotateFlip(RotateFlipType.Rotate270FlipNone); break; + } + } + + /// 作为图像,执行回调。 + /// + /// + public static void AsImage(this byte[] imageData, Action callback) + { + if (imageData == null) throw new ArgumentNullException(nameof(imageData)); + if (callback == null) throw new ArgumentNullException(nameof(callback)); + + using (var stream = new MemoryStream(imageData)) + { + using (var image = Image.FromStream(stream)) + { + AdjustRotation(image); + callback.Invoke(image); + } + } + } + + /// 作为图像,执行回调。 + /// + /// + public static TResult AsImage(this byte[] imageData, Func callback) + { + if (imageData == null) throw new ArgumentNullException(nameof(imageData)); + if (callback == null) throw new ArgumentNullException(nameof(callback)); + + using (var stream = new MemoryStream(imageData)) + { + using (var image = Image.FromStream(stream)) + { + AdjustRotation(image); + return callback.Invoke(image); + } + } + } + /// 保存图像为文件。 /// public static byte[] Save(this Image image, ImageFormat format) @@ -63,6 +129,38 @@ namespace Apewer } } + /// 等比例缩放,生成新图像。 + /// + /// + public static Image AspectScale(this Image origin, int maxSide, Color? backgroundColor = null) => AspectScale(origin, maxSide, maxSide, backgroundColor); + + /// 等比例缩放,生成新图像。 + /// + /// + public static Image AspectScale(this Image origin, int maxWidth, int maxHeight, Color? backgroundColor = null) + { + if (origin == null) throw new ArgumentNullException(nameof(origin)); + if (maxWidth < 1) throw new ArgumentOutOfRangeException(nameof(maxWidth)); + if (maxHeight < 1) throw new ArgumentOutOfRangeException(nameof(maxHeight)); + + var width = origin.Width; + var height = origin.Height; + + var radio = Convert.ToDouble(width) / Convert.ToDouble(height); + if (width > maxWidth) + { + width = maxWidth; + height = Convert.ToInt32(maxWidth / radio); + } + if (height > maxHeight) + { + width = Convert.ToInt32(maxHeight * radio); + height = maxHeight; + } + + return Scale(origin, width, height, backgroundColor); + } + /// 缩放图像,生成新图像。 /// 原始图像。 /// 新图像的大小。 @@ -102,6 +200,7 @@ namespace Apewer if (isTransparentFormat) { if (backgroundColor != null && backgroundColor.HasValue) graphic.Clear(backgroundColor.Value); + else graphic.Clear(Color.Transparent); } // 绘制新图像