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