125 lines
4.6 KiB
C#
125 lines
4.6 KiB
C#
using Oqtane.Enums;
|
|
using SixLabors.ImageSharp.Formats.Png;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using System.IO;
|
|
using System;
|
|
using SixLabors.ImageSharp;
|
|
using Oqtane.Infrastructure;
|
|
using Oqtane.Shared;
|
|
using SixLabors.ImageSharp.Formats;
|
|
using SixLabors.ImageSharp.Formats.Webp;
|
|
using System.Linq;
|
|
|
|
namespace Oqtane.Services
|
|
{
|
|
public class ImageService : IImageService
|
|
{
|
|
private readonly ILogManager _logger;
|
|
private static readonly string[] _formats = ["png", "webp"];
|
|
|
|
public ImageService(ILogManager logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
public string[] GetAvailableFormats()
|
|
{
|
|
return _formats;
|
|
}
|
|
|
|
public string CreateImage(string filepath, int width, int height, string mode, string position, string background, string rotate, string format, string imagepath)
|
|
{
|
|
try
|
|
{
|
|
// params validation
|
|
if (!Enum.TryParse(mode, true, out ResizeMode _)) mode = "crop";
|
|
if (!Enum.TryParse(position, true, out AnchorPositionMode _)) position = "center";
|
|
if (!Color.TryParseHex("#" + background, out _)) background = "transparent";
|
|
if (!int.TryParse(rotate, out _)) rotate = "0";
|
|
rotate = (int.Parse(rotate) < 0 || int.Parse(rotate) > 360) ? "0" : rotate;
|
|
if (!_formats.Contains(format)) format = "png";
|
|
|
|
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
|
|
{
|
|
stream.Position = 0;
|
|
using (var image = Image.Load(stream))
|
|
{
|
|
int.TryParse(rotate, out int angle);
|
|
Enum.TryParse(mode, true, out ResizeMode resizemode);
|
|
Enum.TryParse(position, true, out AnchorPositionMode anchorpositionmode);
|
|
|
|
if (width == 0 && height == 0)
|
|
{
|
|
width = image.Width;
|
|
height = image.Height;
|
|
}
|
|
|
|
IImageEncoder encoder;
|
|
var resizeOptions = new ResizeOptions
|
|
{
|
|
Mode = resizemode,
|
|
Position = anchorpositionmode,
|
|
Size = new Size(width, height)
|
|
};
|
|
|
|
if (background != "transparent")
|
|
{
|
|
resizeOptions.PadColor = Color.ParseHex("#" + background);
|
|
encoder = GetEncoder(format, transparent: false);
|
|
}
|
|
else
|
|
{
|
|
encoder = GetEncoder(format, transparent: true);
|
|
}
|
|
|
|
image.Mutate(x => x
|
|
.AutoOrient() // auto orient the image
|
|
.Rotate(angle)
|
|
.Resize(resizeOptions));
|
|
|
|
image.Save(imagepath, encoder);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, ex, "Error Creating Image For File {FilePath} {Width} {Height} {Mode} {Rotate} {Error}", filepath, width, height, mode, rotate, ex.Message);
|
|
imagepath = "";
|
|
}
|
|
|
|
return imagepath;
|
|
}
|
|
|
|
private static IImageEncoder GetEncoder(string format, bool transparent)
|
|
{
|
|
return format switch
|
|
{
|
|
"png" => GetPngEncoder(transparent),
|
|
"webp" => GetWebpEncoder(transparent),
|
|
_ => GetPngEncoder(transparent),
|
|
};
|
|
}
|
|
|
|
private static PngEncoder GetPngEncoder(bool transparent)
|
|
{
|
|
return new PngEncoder()
|
|
{
|
|
ColorType = transparent ? PngColorType.RgbWithAlpha : PngColorType.Rgb,
|
|
TransparentColorMode = transparent ? PngTransparentColorMode.Preserve : PngTransparentColorMode.Clear,
|
|
BitDepth = PngBitDepth.Bit8,
|
|
CompressionLevel = PngCompressionLevel.BestSpeed
|
|
};
|
|
}
|
|
|
|
private static WebpEncoder GetWebpEncoder(bool transparent)
|
|
{
|
|
return new WebpEncoder()
|
|
{
|
|
FileFormat = WebpFileFormatType.Lossy,
|
|
Quality = 60,
|
|
TransparentColorMode = transparent ? WebpTransparentColorMode.Preserve : WebpTransparentColorMode.Clear,
|
|
};
|
|
}
|
|
}
|
|
}
|