This commit is contained in:
parent
ddf47ad51b
commit
d76e133f18
31 changed files with 236 additions and 2592 deletions
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
// System.Drawing not required for ImageSharp-based drawing in this class
|
||||
using Microsoft.Extensions.Logging;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
|
|
@ -17,11 +16,8 @@ using SixLabors.ImageSharp.Drawing;
|
|||
namespace MaddoShared;
|
||||
|
||||
/// <summary>
|
||||
/// Image creator implemented using SixLabors.ImageSharp for core image operations.
|
||||
/// This implementation focuses on loading, EXIF-orientation, resizing and saving.
|
||||
/// It intentionally implements a minimal subset of the original functionality to
|
||||
/// provide a safe and testable replacement. Additional features (text/logo drawing)
|
||||
/// can be added later using ImageSharp.Drawing.Common and SixLabors.Fonts.
|
||||
/// Image creator implemented with SixLabors.ImageSharp for loading, EXIF orientation,
|
||||
/// resizing, text/logo drawing, and saving.
|
||||
/// </summary>
|
||||
public class ImageCreatorImageSharp : IImageCreator
|
||||
{
|
||||
|
|
@ -38,12 +34,11 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
{
|
||||
ArgumentNullException.ThrowIfNull(imgState);
|
||||
|
||||
// Minimal preparation of names and settings normally done by ImageCreatorSharp.PrepareVariables
|
||||
PrepareVariablesMinimal(imgState);
|
||||
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("[Alternate] Processing {File} -> {Dest}", imgState.WorkFile?.FullName, imgState.DestDir?.FullName);
|
||||
_logger.LogInformation("[ImageSharp] Processing {File} -> {Dest}", imgState.WorkFile?.FullName, imgState.DestDir?.FullName);
|
||||
|
||||
using var fs = File.OpenRead(imgState.WorkFile.FullName);
|
||||
|
||||
|
|
@ -59,9 +54,6 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
// text to draw (horizontal vs vertical).
|
||||
ApplyExifOrientation(img, imgState);
|
||||
|
||||
// Determine output format
|
||||
var forceJpg = _picSettings.UsaForzaJpg;
|
||||
|
||||
// Compute big size
|
||||
var bigSize = ComputeBigSize(img.Width, img.Height);
|
||||
|
||||
|
|
@ -71,10 +63,10 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
// Ensure destination exists
|
||||
imgState.DestDir?.Create();
|
||||
|
||||
var fileNameBig = System.IO.Path.Combine(imgState.DestDir.FullName, imgState.NomeFileBig);
|
||||
var fileNameBig = System.IO.Path.Combine(imgState.DestDir.FullName, imgState.NomeFileBig);
|
||||
|
||||
// Draw overlays (text/logo) onto big image using ImageSharp and save
|
||||
await DrawAndSaveWithGdiAsync(imgBig, fileNameBig, imgState, logoData, _picSettings.JpegQuality, isThumbnail: false).ConfigureAwait(false);
|
||||
await DrawAndSaveAsync(imgBig, fileNameBig, imgState, logoData, _picSettings.JpegQuality, isThumbnail: false).ConfigureAwait(false);
|
||||
|
||||
// Create thumbnail if requested
|
||||
if (_picSettings.CreaMiniature)
|
||||
|
|
@ -85,20 +77,16 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
var fileNameSmall = System.IO.Path.Combine(imgState.DestDir.FullName, imgState.NomeFileSmall);
|
||||
|
||||
// Draw overlays and save thumbnail via ImageSharp
|
||||
await DrawAndSaveWithGdiAsync(imgSmall, fileNameSmall, imgState, logoData, _picSettings.JpegQualityMin, isThumbnail: true).ConfigureAwait(false);
|
||||
await DrawAndSaveAsync(imgSmall, fileNameSmall, imgState, logoData, _picSettings.JpegQualityMin, isThumbnail: true).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "[Alternate] Error processing image {File}", imgState.WorkFile?.Name);
|
||||
_logger.LogError(ex, "[ImageSharp] Error processing image {File}", imgState.WorkFile?.Name);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Thumbnail overlays are rendered by the GDI+ pass in DrawAndSaveWithGdiAsync to match original rendering.
|
||||
|
||||
private static SixLabors.ImageSharp.Formats.IImageEncoder GetEncoderForExtension(string ext, long quality)
|
||||
{
|
||||
quality = Math.Clamp(quality, 1, 100);
|
||||
|
|
@ -110,7 +98,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
};
|
||||
}
|
||||
|
||||
private async Task DrawAndSaveWithGdiAsync(Image<Rgba32> imgSharp, string outputPath, ImageState imgState, byte[]? logoData, long quality, bool isThumbnail)
|
||||
private async Task DrawAndSaveAsync(Image<Rgba32> imgSharp, string outputPath, ImageState imgState, byte[]? logoData, long quality, bool isThumbnail)
|
||||
{
|
||||
// Use ImageSharp drawing APIs to render text and logos and save using ImageSharp encoders.
|
||||
// Clone editable image so we don't mutate the original reference unexpectedly.
|
||||
|
|
@ -125,13 +113,13 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogDebug(ex, "[Alternate] Failed to clear EXIF orientation on working image");
|
||||
_logger?.LogDebug(ex, "[ImageSharp] Failed to clear EXIF orientation on working image");
|
||||
}
|
||||
|
||||
// Ensure DataFoto is set (extracted earlier) so time-based text is available
|
||||
imgState.DataFoto = imgState.CreationDate ?? DateTime.Now;
|
||||
|
||||
// Ensure thumbnail text is prepared similarly to ImageCreatorSharp logic
|
||||
// Ensure thumbnail text is prepared before drawing.
|
||||
if (isThumbnail)
|
||||
{
|
||||
if (string.IsNullOrEmpty(imgState.TestoFirmaPiccola))
|
||||
|
|
@ -285,8 +273,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
});
|
||||
}
|
||||
|
||||
// Draw logo if provided. For compatibility with the original GDI implementation,
|
||||
// do not draw the logo on thumbnails (ImageCreatorSharp only draws logos on big images).
|
||||
// Draw logos only on full-size images.
|
||||
if (logoData != null && logoData.Length > 0 && _picSettings.LogoAggiungi && !isThumbnail)
|
||||
{
|
||||
try
|
||||
|
|
@ -414,7 +401,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "[Alternate] Invalid transparent color setting {Color}", _picSettings.TransparentColor);
|
||||
_logger.LogError(ex, "[ImageSharp] Invalid transparent color setting {Color}", _picSettings.TransparentColor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +416,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "[Alternate] Error drawing logo in ImageSharp pass");
|
||||
_logger.LogError(ex, "[ImageSharp] Error drawing logo");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -444,8 +431,6 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
await working.SaveAsync(outStream, encoder).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// Removed GDI encoder helper; ImageSharp encoders are used instead.
|
||||
|
||||
private void PrepareVariablesMinimal(ImageState imgState)
|
||||
{
|
||||
imgState.NomeFileBig = imgState.WorkFile.Name;
|
||||
|
|
@ -454,7 +439,6 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
imgState.DimensioneStandardMiniatura = _picSettings.DimStandardMiniatura;
|
||||
|
||||
// basic text / transparency defaults used by drawing routines
|
||||
// AlphaScelta mirrors ImageCreatorSharp behavior: compute from PicSettings.Trasparenza (0-100)
|
||||
imgState.AlphaScelta = Convert.ToInt32((255 * (100 - _picSettings.Trasparenza) / (double)100));
|
||||
|
||||
// Set minimal text fields so text drawing has fallback values
|
||||
|
|
@ -517,9 +501,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
|
||||
private void ApplyExifOrientation(Image<Rgba32> img, ImageState imgState)
|
||||
{
|
||||
// Common EXIF orientations: 1=TopLeft, 3=BottomRight (rotate 180), 6=RightTop (rotate 90 CW), 8=LeftBottom (rotate 270 CW)
|
||||
// Set rotation flags on the state so other code can pick the correct
|
||||
// text variant (vertical vs horizontal). Mirror ImageCreatorSharp logic.
|
||||
// Set rotation flags on the state so other code can pick the correct text variant.
|
||||
imgState.FotoRuotaADestra = false;
|
||||
imgState.FotoRuotaASinistra = false;
|
||||
|
||||
|
|
@ -567,11 +549,11 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
catch (Exception ex)
|
||||
{
|
||||
// Non-fatal: log and continue
|
||||
_logger?.LogDebug(ex, "[Alternate] Could not clear EXIF orientation tag");
|
||||
_logger?.LogDebug(ex, "[ImageSharp] Could not clear EXIF orientation tag");
|
||||
}
|
||||
}
|
||||
|
||||
private System.Drawing.Size ComputeBigSize(int width, int height)
|
||||
private Size ComputeBigSize(int width, int height)
|
||||
{
|
||||
// If original large size option requested, return original
|
||||
// otherwise compute based on width/height limits from settings
|
||||
|
|
@ -580,16 +562,14 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
: CalculateThumbnailSize(width, height, _picSettings.AltezzaBig, "Altezza");
|
||||
}
|
||||
|
||||
private System.Drawing.Size ComputeSmallSize(int width, int height)
|
||||
private Size ComputeSmallSize(int width, int height)
|
||||
{
|
||||
return width > height
|
||||
? CalculateThumbnailSize(width, height, _picSettings.LarghezzaSmall, "Larghezza")
|
||||
: CalculateThumbnailSize(width, height, _picSettings.AltezzaSmall, "Altezza");
|
||||
}
|
||||
|
||||
// Helper to access PicSettings values via instance _picSettings
|
||||
|
||||
private static System.Drawing.Size CalculateThumbnailSize(int currentwidth, int currentheight, int maxPixel, string tipoSize)
|
||||
private static Size CalculateThumbnailSize(int currentwidth, int currentheight, int maxPixel, string tipoSize)
|
||||
{
|
||||
double tempMultiplier;
|
||||
if (string.Equals(tipoSize, "Larghezza", StringComparison.OrdinalIgnoreCase))
|
||||
|
|
@ -601,7 +581,7 @@ public class ImageCreatorImageSharp : IImageCreator
|
|||
else
|
||||
tempMultiplier = maxPixel / (double)currentwidth;
|
||||
|
||||
var newSize = new System.Drawing.Size(Convert.ToInt32(currentwidth * tempMultiplier), Convert.ToInt32(currentheight * tempMultiplier));
|
||||
var newSize = new Size(Convert.ToInt32(currentwidth * tempMultiplier), Convert.ToInt32(currentheight * tempMultiplier));
|
||||
return newSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue