using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Net.Http; using System.Runtime.InteropServices; using System.Threading.Tasks; using Avalonia; using Avalonia.Media.Imaging; using Avalonia.Platform; using Bitmap = System.Drawing.Bitmap; using PixelFormat = Avalonia.Platform.PixelFormat; namespace DispenserUI.Utils; #pragma warning disable CA1416 public static class ImageHelper { private static readonly ImageCodecInfo JpgEncoder = GetEncoderInfo("image/jpeg"); private static readonly ImageCodecInfo PngEncoder = GetEncoderInfo("image/png"); private static readonly Encoder Encoder = Encoder.Quality; private static readonly EncoderParameter[] parameterList = new EncoderParameter[101]; /// /// 加载指定路径的资源,转换成Bitmap格式 /// /// /// public static Bitmap LoadFromResource(Uri resourceUri) { return new Bitmap(AssetLoader.Open(resourceUri)); } /// /// 从网络上加载资源 /// /// /// public static async Task LoadFromWeb(Uri url) { using var httpClient = new HttpClient(); try { var response = await httpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var data = await response.Content.ReadAsByteArrayAsync(); return new Bitmap(new MemoryStream(data)); } catch (HttpRequestException ex) { Console.WriteLine($"加载图片失败 '{url}' : {ex.Message}"); return null; } } public static Avalonia.Media.Imaging.Bitmap ToJpg(Image image) { // 将System.Drawing.Image保存到内存流中 using var memoryStream = new MemoryStream(); image.Save(memoryStream, ImageFormat.Jpeg); // 保存为PNG格式 memoryStream.Position = 0; // 重置流位置 // 从内存流创建Avalonia的Bitmap return new Avalonia.Media.Imaging.Bitmap(memoryStream); } /// /// 将 bmp 转为 jpg /// /// /// /// public static Bitmap ConvertBmpToJpg(Image bmp, int quality) { // 创建一个新的Bitmap对象,复制原始BMP图像的内容 using var bmpImage = new Bitmap(bmp); var encoderParams = new EncoderParameters(1); var encoderParam = new EncoderParameter(Encoder.Quality, quality); encoderParams.Param[0] = encoderParam; // 将BMP转化成JPG var ms = new MemoryStream(); bmpImage.Save(ms, JpgEncoder, encoderParams); // 重新从内存加载已转换的JPG图像,返回Bitmap对象 var convertedImage = new Bitmap(ms); // 清理资源 ms.Close(); ms.Dispose(); return convertedImage; } //获取图像编解码器 private static ImageCodecInfo GetEncoderInfo(string type) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) if (encoders[j].MimeType == type) return encoders[j]; return null; } //该方法根据参数返回包含指定画质的编码信息,value的范围是: [0,100] private static EncoderParameter GetParameter(long value) { var v = (int)value; //为了提高性能,可以将使用过的编码信息保存起来,仅当数组中没有时才重新获取 if (parameterList[v] == null) parameterList[v] = new EncoderParameter(Encoder, value); return parameterList[v]; } public static Avalonia.Media.Imaging.Bitmap LoadBitmap(string path) { if (path.StartsWith("/") || path.StartsWith("\\")) path = path.Substring(1); using var memoryStream = new MemoryStream(); var bitmap = new Bitmap(path); bitmap.Save(memoryStream, ImageFormat.Png); memoryStream.Seek(0, SeekOrigin.Begin); return new Avalonia.Media.Imaging.Bitmap(memoryStream); } public static Avalonia.Media.Imaging.Bitmap LoadPng(string path) { if (path.StartsWith("/") || path.StartsWith("\\")) path = path.Substring(1); var bitmap = new Bitmap(path); // 创建一个内存流存储 System.Drawing.Bitmap 的数据 using (var memoryStream = new MemoryStream()) { // 将 System.Drawing.Bitmap 保存到内存流中 bitmap.Save(memoryStream, ImageFormat.Png); // 重置流的位置到开始 memoryStream.Position = 0; // 使用内存流中的数据创建 Avalonia Bitmap return new Avalonia.Media.Imaging.Bitmap(memoryStream); } } [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count); /// /// 将System.Drawing.Bitmap转换为Avalonia.Media.Imaging.Bitmap /// /// /// public static Avalonia.Media.Imaging.Bitmap ConvertToAvaloniaBitmap(Bitmap source) { var width = source.Width; var height = source.Height; var image = new WriteableBitmap(new PixelSize(4096, 3000), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul); var bitmapData = source.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (var frameBuffer = image.Lock()) { var sourcePtr = bitmapData.Scan0; var destPtr = frameBuffer.Address; var count = (uint)(bitmapData.Stride * source.Height); CopyMemory(destPtr, sourcePtr, count); } source.UnlockBits(bitmapData); return image; } }