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.
172 lines
6.2 KiB
172 lines
6.2 KiB
#if NET40 || NET461
|
|
|
|
using Apewer;
|
|
using Apewer.Internals;
|
|
using Apewer.Internals.QrCode;
|
|
using Apewer.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Apewer.Surface
|
|
{
|
|
|
|
/// <summary>图像实用工具。</summary>
|
|
public static class ImageUtility
|
|
{
|
|
|
|
internal static byte[] EmptyBytes { get { return new byte[0]; } }
|
|
|
|
/// <summary>保存图像到文件。</summary>
|
|
/// <exception cref="ArgumentNullException" />
|
|
public static byte[] SaveAs(this Image image, ImageFormat format)
|
|
{
|
|
if (image == null) throw new ArgumentNullException(nameof(image));
|
|
if (format == null) throw new ArgumentNullException(nameof(format));
|
|
|
|
var memory = new MemoryStream();
|
|
var bytes = null as byte[];
|
|
try
|
|
{
|
|
image.Save(memory, format);
|
|
bytes = memory.ToArray();
|
|
}
|
|
catch { }
|
|
memory.Dispose();
|
|
return bytes;
|
|
}
|
|
|
|
/// <summary>保存为 PNG 文件。</summary>
|
|
/// <exception cref="ArgumentNullException" />
|
|
public static byte[] SaveAsPng(this Image image)
|
|
{
|
|
return SaveAs(image, ImageFormat.Png);
|
|
}
|
|
|
|
/// <summary>保存为 JPEG 文件。</summary>
|
|
/// <exception cref="ArgumentNullException" />
|
|
public static byte[] SaveAsJpeg(this Image image)
|
|
{
|
|
return SaveAs(image, ImageFormat.Jpeg);
|
|
}
|
|
|
|
/// <summary>调整图像尺寸,生成新图像。</summary>
|
|
/// <param name="image">原图像。</param>
|
|
/// <param name="width">新图像的宽度,在缩放时此参数用于限定最大宽度。</param>
|
|
/// <param name="height">新图像的高度,在缩放时此参数用于限定最大高度。</param>
|
|
/// <param name="scale">保持原比例进行缩放。</param>
|
|
/// <returns>新图像。</returns>
|
|
public static Bitmap Resize(this Image image, int width, int height, bool scale = false)
|
|
{
|
|
if (image == null) throw new ArgumentNullException(nameof(image));
|
|
if (width < 0) throw new ArgumentOutOfRangeException(nameof(width));
|
|
if (height < 0) throw new ArgumentOutOfRangeException(nameof(height));
|
|
|
|
var newWidth = width;
|
|
var newHeight = height;
|
|
if (scale)
|
|
{
|
|
newWidth = image.Width;
|
|
newHeight = image.Height;
|
|
var radio = Convert.ToDouble(newWidth) / Convert.ToDouble(newHeight);
|
|
if (newWidth > width)
|
|
{
|
|
newWidth = width;
|
|
newHeight = Convert.ToInt32(width / radio);
|
|
}
|
|
if (newHeight > height)
|
|
{
|
|
newWidth = Convert.ToInt32(height * radio);
|
|
newHeight = height;
|
|
}
|
|
}
|
|
|
|
var bitmap = new Bitmap(newWidth, newHeight);
|
|
try
|
|
{
|
|
using (var graphic = Graphics.FromImage(bitmap))
|
|
{
|
|
graphic.CompositingMode = CompositingMode.SourceOver;
|
|
graphic.CompositingQuality = CompositingQuality.HighQuality;
|
|
graphic.SmoothingMode = SmoothingMode.AntiAlias;
|
|
graphic.Clear(Color.Transparent);
|
|
graphic.DrawImage(image, 0, 0, width, height);
|
|
}
|
|
|
|
return bitmap;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
RuntimeUtility.Dispose(bitmap);
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
/// <summary>生成二维码图像,可指定色块边长像素值和纠错率,失败时返回 NULL 值。</summary>
|
|
public static Bitmap GenerateQrCode(string text, int block = 8)
|
|
{
|
|
return GenerateQrCode(text, block, Color.Black, Color.White);
|
|
}
|
|
|
|
/// <summary>生成二维码图像,可指定色块边长像素值和纠错率,失败时返回 NULL 值。</summary>
|
|
public static Bitmap GenerateQrCode(string text, int block, Color dark, Color light)
|
|
{
|
|
var t = text ?? "";
|
|
var b = block > 1 ? block : 1;
|
|
var ecclevel = QRCodeGenerator.ECCLevel.M;
|
|
|
|
// var ecc = QrCodeEccLevel.M;
|
|
// if (ecc == QrCodeEccLevel.L) ecclevel = QRCodeGenerator.ECCLevel.L;
|
|
// else if (ecc == QrCodeEccLevel.M) ecclevel = QRCodeGenerator.ECCLevel.M;
|
|
// else if (ecc == QrCodeEccLevel.Q) ecclevel = QRCodeGenerator.ECCLevel.Q;
|
|
// else if (ecc == QrCodeEccLevel.H) ecclevel = QRCodeGenerator.ECCLevel.H;
|
|
|
|
try
|
|
{
|
|
var generator = new QRCodeGenerator();
|
|
var content = generator.CreateQrCode(t, ecclevel);
|
|
var qrcode = new QRCode(content);
|
|
var bitmap = qrcode.GetGraphic(b, dark, light, false);
|
|
return bitmap;
|
|
}
|
|
catch { return null; }
|
|
}
|
|
|
|
/// <summary>从 RGBA 十六进制字符串获取颜色。</summary>
|
|
public static Color GetColorByHex(string hex, Color @default)
|
|
{
|
|
var lower = hex.ToLower();
|
|
if (lower == "none" || lower == "alpha" || lower == "transparent")
|
|
{
|
|
return Color.Transparent;
|
|
}
|
|
else
|
|
{
|
|
const string pool = "0123456789abcdef";
|
|
lower = TextUtility.Restrict(lower, pool);
|
|
if (lower.Length >= 6)
|
|
{
|
|
var r = pool.IndexOf(lower[0]) * 16 + pool.IndexOf(lower[1]);
|
|
var g = pool.IndexOf(lower[2]) * 16 + pool.IndexOf(lower[3]);
|
|
var b = pool.IndexOf(lower[4]) * 16 + pool.IndexOf(lower[5]);
|
|
var a = 255;
|
|
if (lower.Length >= 8)
|
|
{
|
|
a = pool.IndexOf(lower[6]) * 16 + pool.IndexOf(lower[7]);
|
|
}
|
|
var color = Color.FromArgb(a, r, g, b);
|
|
return color;
|
|
}
|
|
}
|
|
return @default;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|