#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 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) { 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 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); } /// 缩放图像,生成新图像。 /// 原始图像。 /// 新图像的大小。 /// 填充新图像背景色。 /// /// 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); else graphic.Clear(Color.Transparent); } // 绘制新图像 graphic.DrawImage(image, 0, 0, width, height); } return bitmap; } catch { bitmap.Dispose(); throw; } } } } #endif