Dispenser/DispenserUI/Utils/ImageHelper.cs

179 lines
6.0 KiB
C#
Raw Permalink Normal View History

2024-08-16 07:20:09 +00:00
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];
/// <summary>
/// 加载指定路径的资源转换成Bitmap格式
/// </summary>
/// <param name="resourceUri"></param>
/// <returns></returns>
public static Bitmap LoadFromResource(Uri resourceUri)
{
return new Bitmap(AssetLoader.Open(resourceUri));
}
/// <summary>
/// 从网络上加载资源
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static async Task<Bitmap?> 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);
}
/// <summary>
/// 将 bmp 转为 jpg
/// </summary>
/// <param name="bmp"></param>
/// <param name="quality"></param>
/// <returns></returns>
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);
/// <summary>
/// 将System.Drawing.Bitmap转换为Avalonia.Media.Imaging.Bitmap
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
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;
}
}