using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Furion.RemoteRequest.Extensions;
namespace GDZZ.Core;
///
/// 图片工具类
///
public static class ImageUtil
{
///
/// 获取外网Url图片的二进制数组
///
///
///
public static async Task GetBytesFromUrl(this string url)
{
// 得到图片流
var result = await url.GetAsStreamAsync();
using var binaryReader = new BinaryReader(result.Stream);
// 读取二进制文件流
var resultBytes = binaryReader.ReadBytes(result.Stream.Length.ParseToInt());
binaryReader.Close();
return resultBytes;
}
///
/// 保存二进制流到文件
///
///
///
public static async Task WriteBytesToFile(byte[] content, string fileName)
{
// 检测文件夹是否存在
if (!Directory.Exists(fileName[..fileName.LastIndexOf("/", StringComparison.Ordinal)]))
{
Directory.CreateDirectory(fileName[..fileName.LastIndexOf("/", StringComparison.Ordinal)]);
}
// 检测文件是否存在
if (!File.Exists(fileName))
{
await File.WriteAllBytesAsync(fileName, content);
}
}
///
/// 保存外网Url到文件
///
/// 外网图片Url
/// 要保存的文件名称
///
public static async Task SaveFromUrlToFile(this string url, string fileName)
{
var bytes = await url.GetBytesFromUrl();
await WriteBytesToFile(bytes, fileName);
}
///
/// 删除文件夹里面所有的文件
///
///
///
public static void DeleteFile(this string fileName)
{
foreach (var entry in Directory.GetFileSystemEntries(fileName))
{
if (!File.Exists(entry))
continue;
var name = Path.GetFileNameWithoutExtension(entry);
File.Delete(entry);
}
}
///
/// 无损压缩图片
///
/// 原图片地址
/// 压缩后保存图片地址
/// 压缩后宽度
/// 压缩后高度
/// 压缩质量(数字越小压缩率越高)
/// 压缩后图片的最大大小
/// 是否为第一次调用
///
public static bool CompressImage(string sourceFile, string compressFile, int compressHeight = 750,
int compressWidth = 1334, int flag = 90, int size = 110, bool isFirst = true)
{
// 如果是第一次调用,原始图像的大小小于要压缩的大小,则直接复制文件,并且返回True
var firstFileInfo = new FileInfo(sourceFile);
if (isFirst && firstFileInfo.Length < size * 1024)
{
firstFileInfo.CopyTo(compressFile);
return true;
}
var imageSource = Image.FromFile(sourceFile);
var imageFormat = imageSource.RawFormat;
var sourceWidth = 0;
var sourceHeight = 0;
// 按比例缩放
var temSize = new Size(imageSource.Width, imageSource.Height);
// 处理大小,如果是0,原大小
if (compressHeight.IsNullOrZero())
{
compressHeight = temSize.Height;
}
if (compressWidth.IsNullOrZero())
{
compressWidth = temSize.Width;
}
if (temSize.Width > compressHeight || temSize.Width > compressWidth)
{
if ((temSize.Width * compressHeight) > (temSize.Width * compressWidth))
{
sourceWidth = compressWidth;
sourceHeight = (compressWidth * temSize.Height) / temSize.Width;
}
else
{
sourceWidth = compressHeight;
sourceHeight = (temSize.Height * compressHeight) / temSize.Height;
}
}
else
{
sourceWidth = temSize.Width;
sourceHeight = temSize.Height;
}
var bitmap = new Bitmap(compressWidth, compressHeight);
var graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.Transparent);
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.DrawImage(imageSource,
new Rectangle((compressWidth - sourceWidth) / 2, (compressHeight - sourceHeight) / 2, sourceWidth, sourceHeight),
0, 0, imageSource.Width, imageSource.Height, GraphicsUnit.Pixel);
graphics.Dispose();
// 设置压缩质量
var encoderParameters =
new EncoderParameters {Param = {[0] = new EncoderParameter(Encoder.Quality, new long[] {flag})}};
try
{
// 找到系统中可用的图片编码器信息
var imageCodecInfos = ImageCodecInfo.GetImageEncoders();
var jpegIciInfo = imageCodecInfos.FirstOrDefault(t => t.FormatDescription.Equals("JPEG"));
// 如果编码器存在的,可以压缩
if (jpegIciInfo != null)
{
bitmap.Save(compressFile, jpegIciInfo, encoderParameters);
var fileInfo = new FileInfo(compressFile);
if (fileInfo.Length <= 1024 * size)
return true;
flag -= 10;
CompressImage(sourceFile, compressFile, compressHeight, compressWidth, flag, size, false);
}
else
{
bitmap.Save(compressFile, imageFormat);
}
return true;
}
catch
{
return false;
}
finally
{
imageSource.Dispose();
bitmap.Dispose();
}
}
}