Catalog/CatalogLib/ImgSharpCreator.cs
2017-10-05 14:16:43 +02:00

547 lines
21 KiB
C#

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<Rgba32> _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<Rgba32> 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<Rgba32> 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();
if (PicSettings.Instance.FotoMantieniDimensioni)
{
switch (PicSettings.Instance.ResizeDimension)
{
case ResizeDimensions.LatoLungo:
if (image.Width > image.Height)
{
// larghezza è il lato lungo
size = GetResizeDimensions(new Size(image.Width, image.Height),
new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza),
true);
}
else
{
// altezza è il lato lungo
size = GetResizeDimensions(new Size(image.Width, image.Height),
new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza),
false);
}
break;
case ResizeDimensions.LatoCorto:
if (image.Width > image.Height)
{
// larghezza è il lato lungo
size = GetResizeDimensions(new Size(image.Width, image.Height),
new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza),
false);
}
else
{
// altezza è il lato lungo
size = GetResizeDimensions(new Size(image.Width, image.Height),
new Size(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza),
true);
}
break;
default:
throw new ArgumentOutOfRangeException();
}
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 GetResizeDimensions(Size originalSize, Size newSize, bool isWidth)
{
if (isWidth)
{
return new Size(newSize.Width, originalSize.Height / originalSize.Width * newSize.Height);
}
else
{
return new Size(originalSize.Width / originalSize.Height * newSize.Height, newSize.Height);
}
}
private void SetTextTest(Image<Rgba32> 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<Rgba32> 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<Rgba32> image)
{
//if (string.IsNullOrWhiteSpace(PicSettings.Instance.LogoPath)) return;
//if (!File.Exists(PicSettings.Instance.LogoPath)) return;
//using (Image<Rgba32> logo = Image.Load(PicSettings.Instance.LogoPath))
//{
// Size size = new Size();
// Point location = new Point();
// image.Mutate(x => x.DrawImage(logo, size, location, new GraphicsOptions()
// {
// }));
//}
if (_logo != null)
{
var width = PicSettings.Instance.LogoWidth;
var height = PicSettings.Instance.LogoHeight;
var fattoreAlt = _logo.Height / height;
var fattoreLarg = _logo.Width / width;
var nuovaSize = new Size();
nuovaSize = GetResizeDimensions(new Size(_logo.Width, _logo.Height), new Size(width, height), fattoreLarg > fattoreAlt);
//todo riguardare perché non torna cosa ho fatto
int margineUsato;
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);
}
}
}
private void WriteTextFixed(Image<Rgba32> 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;
}
}
}