179 lines
6.0 KiB
C#
179 lines
6.0 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|