140 lines
4.8 KiB
C#
140 lines
4.8 KiB
C#
using Sarand.Net.Standard.Base.App;
|
|
using Sarand.Net.Standard.Base.Core;
|
|
using Sarand.Net.Standard.Base.Helpers;
|
|
using SixLabors.ImageSharp;
|
|
using SixLabors.ImageSharp.Advanced;
|
|
using SixLabors.ImageSharp.Formats;
|
|
using SixLabors.ImageSharp.PixelFormats;
|
|
using SixLabors.ImageSharp.Processing;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace Sarand.Net.Standard.Base.Utils
|
|
{
|
|
//=======================================================================
|
|
// Image handling methods utilising SixLabors ImageSharp package.
|
|
//=======================================================================
|
|
public static class ImageUtils
|
|
{
|
|
//-------------------------------------------------------------------
|
|
private static readonly String className = typeof(ImageUtils).ToString();
|
|
|
|
//-------------------------------------------------------------------
|
|
public class ImageConfig
|
|
{
|
|
public byte[] ImageData { get; set; }
|
|
public string ImageFormatName;
|
|
public string DefaultMimeType;
|
|
public Sacs.MimeType MimeType;
|
|
public bool ValidImage { get; set; }
|
|
public int Width { get; set; }
|
|
public int Height { get; set; }
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Convert the data stream to an image and extract width and height.
|
|
/// </summary>
|
|
/// <param name="imageData"></param>
|
|
/// <returns>Flag to indicate whether interpretation of image data succeeded.</returns>
|
|
public static ImageConfig VerifyImageData(byte[] imageData)
|
|
{
|
|
String fn = className + ".VerifyImageData";
|
|
ImageConfig imageConfig = new ImageConfig();
|
|
imageConfig.ImageData = imageData;
|
|
try
|
|
{
|
|
IImageFormat imageFormat = null;
|
|
using (var image = LoadImage(imageData, out imageFormat))
|
|
{
|
|
if (image == null) return imageConfig;
|
|
imageConfig.ImageFormatName = imageFormat.Name;
|
|
imageConfig.DefaultMimeType = imageFormat.DefaultMimeType;
|
|
imageConfig.MimeType = EnumUtil.ParseEnum(imageConfig.ImageFormatName, Sacs.MimeType.Unknown);
|
|
imageConfig.Width = image.Width;
|
|
imageConfig.Height = image.Height;
|
|
}
|
|
imageConfig.ValidImage = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
|
}
|
|
return imageConfig;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Load from byte array.
|
|
/// <summary>Convert the data stream to an image.</summary>
|
|
public static SixLabors.ImageSharp.Image LoadImage(byte[] imageData)
|
|
{
|
|
var image = Image.Load<Rgba32>(imageData);
|
|
return image;
|
|
}
|
|
/// <summary>
|
|
/// Convert the data stream to an image.
|
|
/// <para>Identify the image's format on load.</para>
|
|
/// </summary>
|
|
public static SixLabors.ImageSharp.Image LoadImage(byte[] imageData, out IImageFormat format)
|
|
{
|
|
var image = Image.Load<Rgba32>(imageData, out format);
|
|
return image;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// Convert to byte array.
|
|
/// <summary>Convert the data stream to an image.</summary>
|
|
public static Byte[] GetImageData(this SixLabors.ImageSharp.Image image, IImageFormat imageFormat)
|
|
{
|
|
using (MemoryStream ms = new MemoryStream())
|
|
{
|
|
var imageEncoder = image.GetConfiguration().ImageFormatsManager.FindEncoder(imageFormat);
|
|
image.Save(ms, imageEncoder);
|
|
return ms.ToArray();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
/// <summary>
|
|
/// Resize the image with the specified limits, if required.
|
|
/// </summary>
|
|
/// <param name="config">Image data</param>
|
|
/// <param name="widthMax"></param>
|
|
/// <param name="heightMax"></param>
|
|
/// <returns>Flag to indicate whether operation was successful.</returns>
|
|
public static bool ConstrainImage(ImageConfig config, ushort widthMax, ushort heightMax)
|
|
{
|
|
String fn = className + ".ConstrainImage";
|
|
if (widthMax < 1 || heightMax < 1) return false;
|
|
if (config.Width <= widthMax && config.Height <= heightMax) return true;
|
|
config.ValidImage = false;
|
|
|
|
try
|
|
{
|
|
// Resize the image.
|
|
IImageFormat imageFormat = null;
|
|
using (var image = LoadImage(config.ImageData, out imageFormat))
|
|
{
|
|
double resizeProportion = Math.Min(widthMax / (double)image.Width, heightMax / (double)image.Height);
|
|
image.Mutate(img => img.Resize((int)(image.Width * resizeProportion), (int)(image.Height * resizeProportion)));
|
|
config.ImageData = image.GetImageData(imageFormat);
|
|
config.Width = image.Width;
|
|
config.Height = image.Height;
|
|
config.ValidImage = true;
|
|
}
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
SaLogger.Warn(fn + " " + ExceptionUtil.GetLogMessage(exc));
|
|
}
|
|
|
|
return config.ValidImage;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|