Dispenser/DispenserUI/Utils/ImageHelper.cs

179 lines
6.0 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}