2017-02-28 09:59:17 +01:00
using System ;
using System.Collections.Generic ;
2017-03-23 14:36:06 +01:00
using System.Diagnostics ;
2017-02-28 09:59:17 +01:00
using System.IO ;
using System.Linq ;
2017-03-23 14:36:06 +01:00
using System.Numerics ;
2017-02-28 09:59:17 +01:00
using System.Threading.Tasks ;
2017-09-19 15:21:39 +02:00
using MaddoLibrary.Base.Log ;
2017-03-23 14:36:06 +01:00
using SixLabors.Fonts ;
2017-09-19 14:49:29 +02:00
using SixLabors.ImageSharp ;
using SixLabors.ImageSharp.Drawing ;
2017-09-29 14:59:33 +02:00
using SixLabors.ImageSharp.Formats.Jpeg ;
2017-09-25 16:12:21 +02:00
using SixLabors.ImageSharp.MetaData.Profiles.Exif ;
2017-09-20 15:01:22 +02:00
using SixLabors.ImageSharp.Processing ;
2017-09-25 16:12:21 +02:00
using SixLabors.Primitives ;
2017-03-23 14:36:06 +01:00
using Font = SixLabors . Fonts . Font ;
using FontFamily = SixLabors . Fonts . FontFamily ;
using FontStyle = SixLabors . Fonts . FontStyle ;
2017-09-19 14:49:29 +02:00
using Rgba32 = SixLabors . ImageSharp . Rgba32 ;
using Image = SixLabors . ImageSharp . Image ;
2017-02-28 09:59:17 +01:00
namespace CatalogLib
{
public class ImgSharpCreator : IImageProcessor
{
2017-10-05 14:16:43 +02:00
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 ) ;
2017-09-19 14:49:29 +02:00
2017-10-05 14:16:43 +02:00
}
2017-03-23 14:36:06 +01:00
private FileInfo _currentFile ;
2017-02-28 09:59:17 +01:00
public void Start ( FileInfo workFile )
{
2017-09-22 15:26:44 +02:00
Stopwatch s = new Stopwatch ( ) ;
s . Start ( ) ;
2017-03-23 14:36:06 +01:00
_currentFile = workFile ;
2017-04-17 13:06:09 +02:00
2017-06-18 16:23:12 +02:00
using ( Image < Rgba32 > image = Image . Load ( workFile . FullName ) /* new Image(workFile.FullName)*/ )
2017-02-28 09:59:17 +01:00
{
2017-09-19 15:21:39 +02:00
MaddoLogger . Log ( "Loaded Image: {0}" , workFile . FullName ) ;
2017-07-04 12:40:51 +02:00
//image.Rotate(-90);
2017-09-25 16:12:21 +02:00
bool isRotated ;
2017-03-16 18:48:25 +01:00
2017-09-25 16:12:21 +02:00
var orientation = image . MetaData . ExifProfile . GetValue ( ExifTag . Orientation ) ;
if ( ( ushort ) orientation . Value ! = 1 )
{
isRotated = true ;
}
else
{
isRotated = false ;
}
if ( PicSettings . Instance . FotoRidimensiona )
{
2017-09-29 14:59:33 +02:00
Resize ( image ) ;
2017-09-25 16:12:21 +02:00
}
2017-09-20 15:01:22 +02:00
2017-09-29 14:59:33 +02:00
2017-07-04 12:40:51 +02:00
if ( PicSettings . Instance . GeneraleRotazioneAutomatica )
{
2017-09-19 14:49:29 +02:00
image . Mutate ( img = > img . AutoOrient ( ) ) ;
2017-09-19 15:21:39 +02:00
MaddoLogger . Log ( "Rotated Image: {0}" , workFile . FullName ) ;
2017-09-19 14:49:29 +02:00
//image.AutoOrient();
2017-07-04 12:40:51 +02:00
//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;
// }
// }
//}
2017-03-16 18:48:25 +01:00
}
2017-04-17 13:06:09 +02:00
if ( PicSettings . Instance . EnableText )
{
2017-09-27 17:12:36 +02:00
//SetTextTest(image);
2017-09-29 14:59:33 +02:00
SetExtraText ( image , isRotated ) ;
2017-09-25 16:12:21 +02:00
2017-09-19 15:21:39 +02:00
MaddoLogger . Log ( "Drawn text on Image: {0}" , workFile . FullName ) ;
2017-04-17 13:06:09 +02:00
}
2017-03-23 14:36:06 +01:00
2017-03-16 18:48:25 +01:00
//JpegDecoder j = new JpegDecoder();
2017-03-23 14:36:06 +01:00
var va = Vector . IsHardwareAccelerated ;
2017-09-19 15:21:39 +02:00
MaddoLogger . Log ( "Hardware Accelerated: {0}" , va ) ;
2017-04-18 08:26:28 +02:00
//image.Resize(PicSettings.Instance.FotoLarghezza, PicSettings.Instance.FotoAltezza);
2017-03-23 14:36:06 +01:00
//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));
2017-10-05 14:16:43 +02:00
image . Save ( Path . Combine ( PicSettings . Instance . DirectoryDestinazione , workFile . Name ) , new JpegEncoder ( ) { Quality = PicSettings . Instance . CompressioneJpeg } ) ;
2017-03-16 18:48:25 +01:00
//image.Resize(200, 200).Save("");
2017-09-22 15:26:44 +02:00
2017-09-19 15:21:39 +02:00
MaddoLogger . Log ( "Saved Image: {0} to: {1}" , workFile . FullName , Path . Combine ( PicSettings . Instance . DirectoryDestinazione , workFile . Name ) ) ;
2017-02-28 09:59:17 +01:00
}
2017-09-22 15:26:44 +02:00
s . Stop ( ) ;
MaddoLogger . Log ( "Time Taken for {0}: {1}" , workFile . FullName , s . Elapsed ) ;
2017-02-28 09:59:17 +01:00
}
2017-03-17 16:23:29 +01:00
2017-09-29 14:59:33 +02:00
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
2017-10-19 14:37:55 +02:00
var size = new Size ( PicSettings . Instance . FotoLarghezza , PicSettings . Instance . FotoAltezza ) ;
2017-09-29 14:59:33 +02:00
if ( PicSettings . Instance . FotoMantieniDimensioni )
{
2017-10-19 14:37:55 +02:00
size = ResizeImage ( image , size , PicSettings . Instance . ResizeDimension ) ;
2017-10-05 14:16:43 +02:00
image . Mutate ( x = > x . Resize ( ( size . Width ) , ( size . Height ) , resampler ) ) ;
2017-09-29 14:59:33 +02:00
//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 ) ) ;
}
}
2017-10-19 14:37:55 +02:00
private Size ResizeImage ( Image < Rgba32 > image , Size size , ResizeDimensions side )
2017-09-29 14:59:33 +02:00
{
2017-10-19 14:37:55 +02:00
switch ( side )
2017-09-29 14:59:33 +02:00
{
2017-10-19 14:37:55 +02:00
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 ( ) ;
2017-09-29 14:59:33 +02:00
}
2017-10-19 14:37:55 +02:00
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 ) ;
2017-09-29 14:59:33 +02:00
}
2017-09-27 17:12:36 +02:00
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
} ) ) ;
}
2017-09-25 16:12:21 +02:00
private void SetExtraText ( Image < Rgba32 > image , bool isRotated )
2017-03-17 16:23:29 +01:00
{
2017-03-23 14:36:06 +01:00
if ( string . IsNullOrWhiteSpace ( PicSettings . Instance . TestoApplicareOrizzontale ) )
{
Debug . WriteLine ( $"{_currentFile.Name} No text" ) ;
return ;
}
2017-07-04 12:40:51 +02:00
2017-09-25 16:12:21 +02:00
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 ( "$_" , "" ) ;
}
2017-07-04 12:40:51 +02:00
var fo = SixLabors . Fonts . SystemFonts . Find ( PicSettings . Instance . NomeFont ) ;
//var fff = FontCollection.SystemFonts.Find(PicSettings.Instance.NomeFont);
2017-03-23 14:36:06 +01:00
//var fff = FontCollection.SystemFonts.Find("Segoe Print");
2017-09-25 16:12:21 +02:00
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
2017-09-29 14:59:33 +02:00
2017-03-23 14:36:06 +01:00
//var font = new Font(fff, 8f, FontStyle.Regular);
2017-06-18 16:23:12 +02:00
//Color c = Color.FromHex(FlipRgbString(PicSettings.Instance.ColoreTestoRGB));
Rgba32 g = Rgba32 . FromHex ( FlipRgbString ( PicSettings . Instance . ColoreTestoRGB ) ) ;
2017-09-25 16:12:21 +02:00
Rgba32 gBack = Rgba32 . Black ; // todo alpha
2017-07-04 12:40:51 +02:00
//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));
2017-04-18 08:26:28 +02:00
2017-07-04 12:40:51 +02:00
Vector2 center = new Vector2 ( image . Width / 2 , image . Height / 2 ) ; //center horizontally, 10px down
2017-09-25 16:12:21 +02:00
var size = TextMeasurer . Measure ( text , new RendererOptions ( font ) ) ;
var larghezzaStandard = size . Width ;
2017-09-29 14:59:33 +02:00
var dimensioneStandard = ( int ) Math . Round ( PicSettings . Instance . DimensioneFont ) ;
2017-09-25 16:12:21 +02:00
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 )
{
2017-09-29 14:59:33 +02:00
larghezzaStandard = ( int ) Math . Round ( size . Width ) ;
2017-09-25 16:12:21 +02:00
break ;
}
if ( c < = 5 )
{
break ;
}
} while ( dimensioneStandard = = c ) ;
}
float yPosFromBottom = 0 ;
switch ( PicSettings . Instance . TextPosition )
{
2017-09-27 17:12:36 +02:00
case Positions . Alto :
2017-09-25 16:12:21 +02:00
yPosFromBottom = PicSettings . Instance . Margine ;
break ;
2017-09-27 17:12:36 +02:00
case Positions . Basso :
2017-09-25 16:12:21 +02:00
yPosFromBottom = image . Height - size . Height - ( image . Height * PicSettings . Instance . Margine / 100 ) ;
break ;
}
float xCenterofImg = 0 ;
2017-09-29 14:59:33 +02:00
2017-09-25 16:12:21 +02:00
// stringformat
switch ( PicSettings . Instance . TextAlignment )
{
2017-09-27 17:12:36 +02:00
case Alignments . Sinistra :
2017-09-25 16:12:21 +02:00
xCenterofImg = PicSettings . Instance . Margine + ( larghezzaStandard / 2 ) ;
if ( ( larghezzaStandard / 2 ) > ( image . Width / 2 ) - PicSettings . Instance . Margine )
{
xCenterofImg = image . Width / 2 ;
}
break ;
2017-09-27 17:12:36 +02:00
case Alignments . Centro :
2017-09-25 16:12:21 +02:00
xCenterofImg = image . Width / 2 ;
break ;
2017-09-27 17:12:36 +02:00
case Alignments . Destra :
2017-09-25 16:12:21 +02:00
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 ) ;
}
2017-09-29 14:59:33 +02:00
image . Mutate ( x = > x . DrawText ( text , font , gBack , new PointF ( ( float ) Math . Round ( xCenterofImg + 1 ) , ( float ) Math . Round ( yPosFromBottom + 1 ) ) , new TextGraphicsOptions ( )
2017-09-25 16:12:21 +02:00
{
HorizontalAlignment = HorizontalAlignment . Center
} ) ) ;
2017-09-28 14:50:24 +02:00
image . Mutate ( x = > x . DrawText ( text , font , g , new PointF ( ( float ) Math . Round ( xCenterofImg ) , ( float ) Math . Round ( yPosFromBottom ) ) , new TextGraphicsOptions ( )
2017-09-25 16:12:21 +02:00
{
HorizontalAlignment = HorizontalAlignment . Center
} ) ) ;
return ;
2017-04-18 08:26:28 +02:00
float scalingFactor = Math . Min ( image . Width / size . Width , image . Height / size . Height ) ;
Font scaledFont = new Font ( font , scalingFactor * font . Size ) ;
2017-09-20 15:01:22 +02:00
image . Mutate ( x = >
x . DrawText ( PicSettings . Instance . TestoApplicareOrizzontale , scaledFont , g , center ,
new TextGraphicsOptions ( true )
{
HorizontalAlignment = HorizontalAlignment . Center ,
VerticalAlignment = VerticalAlignment . Bottom
} ) ) ;
2017-09-19 15:21:39 +02:00
//image.DrawText(PicSettings.Instance.TestoApplicareOrizzontale, scaledFont, g, center, new TextGraphicsOptions(true) { HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Bottom });
2017-07-04 12:40:51 +02:00
2017-03-23 14:36:06 +01:00
2017-07-04 12:40:51 +02:00
}
2017-10-05 14:16:43 +02:00
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()
// {
// }));
//}
2017-10-19 14:37:55 +02:00
Size size = new Size ( ) ;
Point location = new Point ( ) ;
2017-10-05 14:16:43 +02:00
if ( _logo ! = null )
{
var width = PicSettings . Instance . LogoWidth ;
var height = PicSettings . Instance . LogoHeight ;
2017-10-19 14:37:55 +02:00
var heightFactor = _logo . Height / height ;
var widthFactor = _logo . Width / width ;
var newLogoSize = new Size ( ) ;
2017-10-05 14:16:43 +02:00
2017-10-19 14:37:55 +02:00
newLogoSize = GetResizeDimensions ( new Size ( _logo . Width , _logo . Height ) , new Size ( width , height ) , PicSettings . Instance . LogoResizeSide . Equals ( ResizeDimensions . LatoCorto ) ) ;
2017-10-05 14:16:43 +02:00
//todo riguardare perché non torna cosa ho fatto
2017-10-19 14:37:55 +02:00
int margineUsato = 0 ;
2017-10-05 14:16:43 +02:00
int margineL ;
bool inPercentualeL ;
inPercentualeL = PicSettings . Instance . LogoMargin . EndsWith ( "%" ) ;
if ( inPercentualeL )
2017-10-19 14:37:55 +02:00
{
margineL = int . Parse ( PicSettings . Instance . LogoMargin . Replace ( "%" , "" ) ) ;
}
2017-10-05 14:16:43 +02:00
else
{
margineL = int . Parse ( PicSettings . Instance . LogoMargin ) ;
}
2017-10-19 14:37:55 +02:00
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 ( ) ) ) ;
2017-10-05 14:16:43 +02:00
}
}
2017-07-04 12:40:51 +02:00
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 ) ;
2017-09-19 15:21:39 +02:00
image . Mutate ( x = > x . DrawText ( "Test test test test test" , scaledFont , g , center , new TextGraphicsOptions ( true ) { HorizontalAlignment = HorizontalAlignment . Center , VerticalAlignment = VerticalAlignment . Bottom } ) ) ;
2017-03-17 16:23:29 +01:00
}
2017-04-18 08:26:28 +02:00
private string FlipRgbString ( string originalString )
{
2017-07-04 12:40:51 +02:00
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 ) ) ;
}
2017-04-18 08:26:28 +02:00
return s ;
}
2017-02-28 09:59:17 +01:00
}
}