using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; using System.Threading.Tasks; using MaddoLibrary.Base.Log; using SixLabors.Fonts; using SixLabors.ImageSharp; using SixLabors.ImageSharp.Drawing; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.MetaData.Profiles.Exif; using SixLabors.ImageSharp.Processing; using SixLabors.Primitives; using Font = SixLabors.Fonts.Font; using FontFamily = SixLabors.Fonts.FontFamily; using FontStyle = SixLabors.Fonts.FontStyle; using Rgba32 = SixLabors.ImageSharp.Rgba32; using Image = SixLabors.ImageSharp.Image; namespace CatalogLib { public class ImgSharpCreator : IImageProcessor { private Image _logo; public ImgSharpCreator() { if (!PicSettings.Instance.EnableLogo) return; if (string.IsNullOrWhiteSpace(PicSettings.Instance.LogoPath)) return; if (!File.Exists(PicSettings.Instance.LogoPath)) return; _logo = Image.Load(PicSettings.Instance.LogoPath); } private FileInfo _currentFile; public void Start(FileInfo workFile) { Stopwatch s = new Stopwatch(); s.Start(); _currentFile = workFile; using (Image image = Image.Load(workFile.FullName)/* new Image(workFile.FullName)*/) { MaddoLogger.Log("Loaded Image: {0}", workFile.FullName); //image.Rotate(-90); bool isRotated; var orientation = image.MetaData.ExifProfile.GetValue(ExifTag.Orientation); if ((ushort)orientation.Value != 1) { isRotated = true; } else { isRotated = false; } if (PicSettings.Instance.FotoRidimensiona) { Resize(image); } if (PicSettings.Instance.GeneraleRotazioneAutomatica) { image.Mutate(img => img.AutoOrient()); MaddoLogger.Log("Rotated Image: {0}", workFile.FullName); //image.AutoOrient(); //var exif = image.MetaData.ExifProfile; //if (exif != null) //{ // var o = exif.GetValue(ExifTag.Orientation); // if (o != null) // { // var v = (ushort)o.Value; // switch (v) // { // //1 = Horizontal(normal) // //2 = Mirror horizontal // //3 = Rotate 180 // //4 = Mirror vertical // //5 = Mirror horizontal and rotate 270 CW // //6 = Rotate 90 CW // //7 = Mirror horizontal and rotate 90 CW // //8 = Rotate 270 CW // case 1: // break; // case 2: // image.Flip(FlipType.Horizontal); // break; // case 3: // //image.Rotate(180f); // //image.Rotate(90); // image.Rotate(RotateType.Rotate180); // break; // case 4: // image.Flip(FlipType.Vertical); // break; // case 5: // image.RotateFlip(RotateType.Rotate270, FlipType.Horizontal); // break; // case 6: // image.Rotate(RotateType.Rotate90); // break; // case 7: // image.RotateFlip(RotateType.Rotate90, FlipType.Horizontal); // break; // case 8: // //image.Rotate(-90); // image.Rotate(RotateType.Rotate270); // image.MetaData.ExifProfile.SetValue(ExifTag.Orientation, new ExifValue(exif.GetValue(ExifTag.Orientation)).Value = (ushort)1); // break; // } // } //} } if (PicSettings.Instance.EnableText) { //SetTextTest(image); SetExtraText(image, isRotated); MaddoLogger.Log("Drawn text on Image: {0}", workFile.FullName); } //JpegDecoder j = new JpegDecoder(); var va = Vector.IsHardwareAccelerated; MaddoLogger.Log("Hardware Accelerated: {0}", va); //image.Resize(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza); //image.Resize(2240, 2240); //var fff = FontCollection.SystemFonts.Find(PicSettings.Instance.NomeFont); //var font = new Font(fff, (float)PicSettings.Instance.DimensioneFont, FontStyle.Regular); //image.DrawText("sssssssssssssssssssssssssssssssssssssssssssssss", font, Color.Black, new Vector2(200, 200)); image.Save(Path.Combine(PicSettings.Instance.DirectoryDestinazione, workFile.Name), new JpegEncoder() { Quality = PicSettings.Instance.CompressioneJpeg }); //image.Resize(200, 200).Save(""); MaddoLogger.Log("Saved Image: {0} to: {1}", workFile.FullName, Path.Combine(PicSettings.Instance.DirectoryDestinazione, workFile.Name)); } s.Stop(); MaddoLogger.Log("Time Taken for {0}: {1}", workFile.FullName, s.Elapsed); } private void Resize(Image image) { IResampler resampler; switch (PicSettings.Instance.ResizeMode) { case ResizeModes.Bicubic: resampler = new BicubicResampler(); break; case ResizeModes.Box: resampler = new BoxResampler(); break; case ResizeModes.CatmullRom: resampler = new CatmullRomResampler(); break; case ResizeModes.Hermite: resampler = new HermiteResampler(); break; case ResizeModes.Lanczos2: resampler = new Lanczos2Resampler(); break; case ResizeModes.Lanczos3: resampler = new Lanczos3Resampler(); break; case ResizeModes.Lanczos5: resampler = new Lanczos5Resampler(); break; case ResizeModes.Lanczos8: resampler = new Lanczos8Resampler(); break; case ResizeModes.MitchellNetravali: resampler = new MitchellNetravaliResampler(); break; case ResizeModes.NearestNeighbor: resampler = new NearestNeighborResampler(); break; case ResizeModes.Robidoux: resampler = new RobidouxResampler(); break; case ResizeModes.Spline: resampler = new SplineResampler(); break; case ResizeModes.Triangle: resampler = new TriangleResampler(); break; case ResizeModes.Welch: resampler = new WelchResampler(); break; default: throw new ArgumentOutOfRangeException(); } // todo calcolare ridimensionamento var size = new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza); if (PicSettings.Instance.FotoMantieniDimensioni) { size = ResizeImage(image, size, PicSettings.Instance.ResizeDimension); image.Mutate(x => x.Resize((size.Width), (size.Height), resampler)); //Width Formula: //original height / original width * new width = new height //Height Formula: //orignal width / orignal height * new height = new width } else { image.Mutate(x => x.Resize(PicSettings.Instance.FotoAltezza, PicSettings.Instance.FotoLarghezza, resampler)); } } private Size ResizeImage(Image image, Size size, ResizeDimensions side) { switch (side) { case ResizeDimensions.LatoLungo: size = GetResizeDimensions(new Size(image.Width, image.Height), size, image.Width > image.Height); break; case ResizeDimensions.LatoCorto: size = GetResizeDimensions(new Size(image.Width, image.Height), size, image.Width <= image.Height); break; default: throw new ArgumentOutOfRangeException(); } return size; } private Size GetResizeDimensions(Size originalSize, Size newSize, bool adjustHeight) { return adjustHeight ? new Size(newSize.Width, originalSize.Height / originalSize.Width * newSize.Height) : new Size(originalSize.Width / originalSize.Height * newSize.Height, newSize.Height); } private void SetTextTest(Image image) { string text = "test test test test test testtest test test test test test test"; Font font = new Font(SystemFonts.Find("verdana"), 300, FontStyle.Regular); image.Mutate(x => x.DrawText(text, font, Rgba32.Yellow, new PointF(2760, 3295.54932f), new TextGraphicsOptions() { HorizontalAlignment = HorizontalAlignment.Center })); } private void SetExtraText(Image image, bool isRotated) { if (string.IsNullOrWhiteSpace(PicSettings.Instance.TestoApplicareOrizzontale)) { Debug.WriteLine($"{_currentFile.Name} No text"); return; } string text; if (isRotated) { if (PicSettings.Instance.TestoApplicareOrizzontale.Contains("$_")) { text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", "\r\n"); } else { text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", ""); } } else { text = PicSettings.Instance.TestoApplicareOrizzontale.Replace("$_", ""); } var fo = SixLabors.Fonts.SystemFonts.Find(PicSettings.Instance.NomeFont); //var fff = FontCollection.SystemFonts.Find(PicSettings.Instance.NomeFont); //var fff = FontCollection.SystemFonts.Find("Segoe Print"); Font font; if (!PicSettings.Instance.Grassetto) { font = new Font(fo, (float)PicSettings.Instance.DimensioneFont, FontStyle.Regular); } else { font = new Font(fo, (float)PicSettings.Instance.DimensioneFont, FontStyle.Bold); } // todo corsivo //var font = new Font(fff, 8f, FontStyle.Regular); //Color c = Color.FromHex(FlipRgbString(PicSettings.Instance.ColoreTestoRGB)); Rgba32 g = Rgba32.FromHex(FlipRgbString(PicSettings.Instance.ColoreTestoRGB)); Rgba32 gBack = Rgba32.Black; // todo alpha //TextMeasurer measurer = new TextMeasurer(); //var size = measurer.MeasureText(PicSettings.Instance.TestoApplicareOrizzontale, font, 72); //float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height); //Font scaledFont = new Font(font, scalingFactor * font.Size); //image.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, new Vector2(0, 0)); Vector2 center = new Vector2(image.Width / 2, image.Height / 2); //center horizontally, 10px down var size = TextMeasurer.Measure(text, new RendererOptions(font)); var larghezzaStandard = size.Width; var dimensioneStandard = (int)Math.Round(PicSettings.Instance.DimensioneFont); if (size.Width > image.Width) { var c = dimensioneStandard; do { if (c > 20) { c -= 5; } else { c -= 1; } if (PicSettings.Instance.Grassetto) { font = new Font(fo, c, FontStyle.Bold); } else { font = new Font(fo, c, FontStyle.Regular); } size = TextMeasurer.Measure(text, new RendererOptions(font)); if (size.Width < image.Width) { larghezzaStandard = (int)Math.Round(size.Width); break; } if (c <= 5) { break; } } while (dimensioneStandard == c); } float yPosFromBottom = 0; switch (PicSettings.Instance.TextPosition) { case Positions.Alto: yPosFromBottom = PicSettings.Instance.Margine; break; case Positions.Basso: yPosFromBottom = image.Height - size.Height - (image.Height * PicSettings.Instance.Margine / 100); break; } float xCenterofImg = 0; // stringformat switch (PicSettings.Instance.TextAlignment) { case Alignments.Sinistra: xCenterofImg = PicSettings.Instance.Margine + (larghezzaStandard / 2); if ((larghezzaStandard / 2) > (image.Width / 2) - PicSettings.Instance.Margine) { xCenterofImg = image.Width / 2; } break; case Alignments.Centro: xCenterofImg = image.Width / 2; break; case Alignments.Destra: xCenterofImg = image.Width - PicSettings.Instance.Margine - larghezzaStandard / 2; if (larghezzaStandard / 2 > image.Width / 2 - PicSettings.Instance.Margine) { xCenterofImg = image.Width / 2; } break; } // stringformat alignment center if (PicSettings.Instance.Grassetto) { font = new Font(fo, dimensioneStandard, FontStyle.Bold); } else { font = new Font(fo, dimensioneStandard, FontStyle.Regular); } image.Mutate(x => x.DrawText(text, font, gBack, new PointF((float)Math.Round(xCenterofImg + 1), (float)Math.Round(yPosFromBottom + 1)), new TextGraphicsOptions() { HorizontalAlignment = HorizontalAlignment.Center })); image.Mutate(x => x.DrawText(text, font, g, new PointF((float)Math.Round(xCenterofImg), (float)Math.Round(yPosFromBottom)), new TextGraphicsOptions() { HorizontalAlignment = HorizontalAlignment.Center })); return; float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height); Font scaledFont = new Font(font, scalingFactor * font.Size); image.Mutate(x => x.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom })); //image.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom }); } private void AddLogo(Image image) { //if (string.IsNullOrWhiteSpace(PicSettings.Instance.LogoPath)) return; //if (!File.Exists(PicSettings.Instance.LogoPath)) return; //using (Image logo = Image.Load(PicSettings.Instance.LogoPath)) //{ // Size size = new Size(); // Point location = new Point(); // image.Mutate(x => x.DrawImage(logo, size, location, new GraphicsOptions() // { // })); //} Size size = new Size(); Point location = new Point(); if (_logo != null) { var width = PicSettings.Instance.LogoWidth; var height = PicSettings.Instance.LogoHeight; var heightFactor = _logo.Height / height; var widthFactor = _logo.Width / width; var newLogoSize = new Size(); newLogoSize = GetResizeDimensions(new Size(_logo.Width, _logo.Height), new Size(width, height), PicSettings.Instance.LogoResizeSide.Equals(ResizeDimensions.LatoCorto)); //todo riguardare perché non torna cosa ho fatto int margineUsato = 0; int margineL; bool inPercentualeL; inPercentualeL = PicSettings.Instance.LogoMargin.EndsWith("%"); if (inPercentualeL) { margineL = int.Parse(PicSettings.Instance.LogoMargin.Replace("%", "")); } else { margineL = int.Parse(PicSettings.Instance.LogoMargin); } switch (PicSettings.Instance.LogoPosition) { case Positions.Alto: break; case Positions.Centro: break; case Positions.Basso: break; default: throw new ArgumentOutOfRangeException(); } switch (PicSettings.Instance.LogoAlignment) { case Alignments.Sinistra: location.X = margineUsato; break; case Alignments.Centro: //location.X = image.Width - break; case Alignments.Destra: break; default: throw new ArgumentOutOfRangeException(); } image.Mutate(x => x.DrawImage(_logo, size, location, new GraphicsOptions())); } } private void WriteTextFixed(Image image) { var fo = SixLabors.Fonts.SystemFonts.Find("Microsoft Sans Serif"); var font = new Font(fo, 8, FontStyle.Regular); Rgba32 g = Rgba32.FromHex("#FF00FFFF"); Vector2 center = new Vector2(image.Width / 2, image.Height / 2); var size = TextMeasurer.Measure("Test test test test test", new RendererOptions(font)); float scalingFactor = Math.Min(image.Width / size.Width, image.Height / size.Height); Font scaledFont = new Font(font, scalingFactor * font.Size); image.Mutate(x => x.DrawText("Test test test test test", scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom })); } private string FlipRgbString(string originalString) { string s; if (originalString.Length == 7) { s = string.Concat("#", originalString.Substring(1, 6)); } else { s = string.Concat("#", originalString.Substring(3, 6), originalString.Substring(1, 2)); } return s; } } }