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.Linq; 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; } } //------------------------------------------------------------------- public static bool IsSvg(byte[] imageData) { try { if (!imageData.Contains((byte)'<')) return false; String imageText = Encoding.UTF8.GetString(imageData); if (!imageText.ContainsCI(" /// Convert the data stream to an image and extract width and height. /// /// /// Flag to indicate whether interpretation of image data succeeded. public static ImageConfig VerifyImageData(byte[] imageData) { 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($"{SysUtil.Fn} {ExceptionUtil.GetLogMessage(exc)}"); } return imageConfig; } //------------------------------------------------------------------- /// /// Convert the SVG data stream to an image and extract width and height. /// /// /// Flag to indicate whether interpretation of image data succeeded. public static ImageConfig VerifySvgImageData(byte[] imageData) { ImageConfig imageConfig = new ImageConfig(); imageConfig.ImageData = imageData; imageConfig.ImageFormatName = "svg"; imageConfig.DefaultMimeType = "svg"; imageConfig.MimeType = EnumUtil.ParseEnum(imageConfig.ImageFormatName, Sacs.MimeType.Unknown); imageConfig.Width = 0; imageConfig.Height = 0; imageConfig.ValidImage = true; return imageConfig; } //------------------------------------------------------------------- // Load from byte array. /// Convert the data stream to an image. public static SixLabors.ImageSharp.Image LoadImage(byte[] imageData) { var image = Image.Load(imageData); return image; } /// /// Convert the data stream to an image. /// Identify the image's format on load. /// public static SixLabors.ImageSharp.Image LoadImage(byte[] imageData, out IImageFormat format) { var image = Image.Load(imageData); format = Image.DetectFormat(imageData); return image; } //------------------------------------------------------------------- // Convert to byte array. /// Convert the data stream to an image. public static Byte[] GetImageData(this SixLabors.ImageSharp.Image image, IImageFormat imageFormat) { using (MemoryStream ms = new MemoryStream()) { var imageEncoder = image.Configuration.ImageFormatsManager.GetEncoder(imageFormat); image.Save(ms, imageEncoder); return ms.ToArray(); } } //------------------------------------------------------------------- /// /// Resize the image with the specified limits, if required. /// /// Image data /// /// /// Flag to indicate whether operation was successful. public static bool ConstrainImage(ImageConfig config, ushort widthMax, ushort heightMax) { if (config.Width == 0 || config.Height == 0) return true; 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($"{SysUtil.Fn} {ExceptionUtil.GetLogMessage(exc)}"); } return config.ValidImage; } //------------------------------------------------------------------- } //======================================================================= }