|
|
#if DRAWING
using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imaging;using System.IO;
namespace Apewer{
/// <summary>绘图。</summary>
public static class DrawingUtility {
/// <summary>优化 Graphics 对象的属性,提升绘图质量。</summary>
public static Graphics Optimize(this Graphics graphics) { if (graphics != null) { graphics.CompositingMode = CompositingMode.SourceOver; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.SmoothingMode = SmoothingMode.AntiAlias; } return graphics; }
/// <summary>识别图像的旋转角度并进行调整。</summary>
/// <exception cref="ArgumentNullException"></exception>
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; } }
/// <summary>作为图像,执行回调。</summary>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public static void AsImage(this byte[] imageData, Action<Image> 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); } } }
/// <summary>作为图像,执行回调。</summary>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
public static TResult AsImage<TResult>(this byte[] imageData, Func<Image, TResult> 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); } } }
/// <summary>保存图像为文件。</summary>
/// <exception cref="ArgumentNullException"></exception>
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(); } }
/// <summary>保存为 JPEG 文件。</summary>
/// <param name="image">Image 实例。</param>
/// <param name="quality">JPEG 质量,0 为最低质量,100 为最高质量。</param>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentOutOfRangeException" />
/// <exception cref="System.Runtime.InteropServices.ExternalException" />
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(); } }
/// <summary>等比例缩放,生成新图像。</summary>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Image AspectScale(this Image origin, int maxSide, Color? backgroundColor = null) => AspectScale(origin, maxSide, maxSide, backgroundColor);
/// <summary>等比例缩放,生成新图像。</summary>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
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); }
/// <summary>缩放图像,生成新图像。</summary>
/// <param name="image">原始图像。</param>
/// <param name="size">新图像的大小。</param>
/// <param name="backgroundColor">填充新图像背景色。</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static Bitmap Scale(this Image image, Size size, Color? backgroundColor = null) => Scale(image, size.Width, size.Height, backgroundColor);
/// <summary>缩放图像,生成新图像。</summary>
/// <param name="image">原始图像。</param>
/// <param name="width">新图像的宽度。</param>
/// <param name="height">新图像的高度。</param>
/// <param name="backgroundColor">填充新图像背景色。</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentOutOfRangeException"></exception>
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
|