diff --git a/src/extensions/Wyam.Images/AnchorPosition.cs b/src/extensions/Wyam.Images/AnchorPosition.cs deleted file mode 100644 index b6993d70e..000000000 --- a/src/extensions/Wyam.Images/AnchorPosition.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ImageProcessor; -using ImageProcessor.Imaging; - -namespace Wyam.Images -{ - public enum AnchorPosition - { - Center = 0, - Top = 1, - Bottom = 2, - Left = 3, - Right = 4, - TopLeft = 5, - TopRight = 6, - BottomRight = 7, - BottomLeft = 8 - } -} diff --git a/src/extensions/Wyam.Images/Image.cs b/src/extensions/Wyam.Images/Image.cs index 9f5394822..18b135156 100644 --- a/src/extensions/Wyam.Images/Image.cs +++ b/src/extensions/Wyam.Images/Image.cs @@ -1,18 +1,20 @@ -using ImageProcessor.Imaging; -using ImageProcessor.Imaging.Formats; -using System; +using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Filters; +using SixLabors.ImageSharp.Processing.Transforms; using Wyam.Common.Documents; using Wyam.Common.Execution; using Wyam.Common.IO; using Wyam.Common.Meta; using Wyam.Common.Modules; using Wyam.Common.Tracing; -using Wyam.Common.Util; -using img = ImageProcessor; namespace Wyam.Images { @@ -97,7 +99,7 @@ private void EnsureCurrentInstruction() /// /// /// The current module instance. - public Image Resize(int? width, int? height, AnchorPosition anchor = AnchorPosition.Center) + public Image Resize(int? width, int? height, AnchorPositionMode anchor = AnchorPositionMode.Center) { EnsureCurrentInstruction(); @@ -227,8 +229,7 @@ public Image SetHue(short degrees, bool rotate = false) _currentInstruction.Hue = new HueInstruction { - Degrees = degrees, - Rotate = rotate + Degrees = degrees }; return this; @@ -379,21 +380,21 @@ public Image And } } - private ISupportedImageFormat GetFormat(string extension, ImageInstruction ins) + private IImageFormat GetFormat(string extension, ImageInstruction ins) { - ISupportedImageFormat format = null; + IImageFormat format = null; if (extension.Equals(".jpg", StringComparison.OrdinalIgnoreCase) || extension.Equals(".jpeg", StringComparison.OrdinalIgnoreCase)) { - format = new JpegFormat { Quality = ins.JpegQuality }; + format = ImageFormats.Jpeg; } else if (extension.Equals(".gif", StringComparison.OrdinalIgnoreCase)) { - format = new GifFormat { }; + format = ImageFormats.Gif; } else if (extension.Equals(".png", StringComparison.OrdinalIgnoreCase)) { - format = new PngFormat { }; + format = ImageFormats.Png; } return format; @@ -413,7 +414,7 @@ public IEnumerable Execute(IReadOnlyList inputs, IExecutio return _instructions.Select(instruction => { - ISupportedImageFormat format = GetFormat(relativePath.Extension, instruction); + IImageFormat format = GetFormat(relativePath.Extension, instruction); if (format == null) { return null; @@ -452,84 +453,112 @@ public IEnumerable Execute(IReadOnlyList inputs, IExecutio }); } - private Stream ProcessImage(IDocument input, ISupportedImageFormat format, ImageInstruction ins) + private Stream ProcessImage(IDocument input, IImageFormat format, ImageInstruction ins) { - using (img.ImageFactory imageFactory = new img.ImageFactory(preserveExifData: true)) + // Load, resize, set the format and quality and save an image. + Image image; + using (Stream stream = input.GetStream()) { - // Load, resize, set the format and quality and save an image. - img.ImageFactory fac; - using (Stream stream = input.GetStream()) - { - fac = imageFactory.Load(stream).Format(format); - } + image = SixLabors.ImageSharp.Image.Load(stream); + } + image.Mutate(fac => + { if (ins.IsNeedResize) { if (ins.IsCropRequired) { - var layer = new ResizeLayer( - size: ins.GetCropSize().Value, - anchorPosition: ins.GetAnchorPosition(), - resizeMode: ResizeMode.Crop - ); - - fac.Resize(layer); + fac = fac.Resize(new ResizeOptions + { + Size = ins.GetCropSize().Value, + Position = ins.GetAnchorPosition(), + Mode = ResizeMode.Crop + }); } else { - fac.Resize(ins.GetCropSize().Value); + fac = fac.Resize(ins.GetCropSize().Value); } } foreach (var f in ins.Filters) { - fac.Filter(ins.GetMatrixFilter(f)); + fac = ApplyFilter(fac, f); } if (ins.Brightness.HasValue) { - fac.Brightness(ins.Brightness.Value); + fac = fac.Brightness(ins.Brightness.Value); } if (ins.Constraint.HasValue) { - fac.Constrain(ins.Constraint.Value); + var options = new ResizeOptions { Mode = ResizeMode.Max, Size = ins.GetCropSize().Value }; + fac = fac.Resize(options); } if (ins.Opacity.HasValue) { - fac.Alpha(ins.Opacity.Value); + fac = fac.Opacity(ins.Opacity.Value); } if (ins.Hue != null) { - fac.Hue(ins.Hue.Degrees, ins.Hue.Rotate); + fac = fac.Hue(ins.Hue.Degrees); } if (ins.Tint != null) { - fac.Tint(ins.Tint.Value); + //fac = fac.Tint(ins.Tint.Value); } if (ins.Vignette != null) { - fac.Vignette(ins.Vignette.Value); + //fac = fac.Vignette(ins.Vignette.Value); } if (ins.Saturation.HasValue) { - fac.Saturation(ins.Saturation.Value); + fac = fac.Saturate(ins.Saturation.Value); } if (ins.Contrast.HasValue) { - fac.Contrast(ins.Contrast.Value); + fac = fac.Contrast(ins.Contrast.Value); } + }); + + var outputStream = new MemoryStream(); + image.Save(outputStream, format); + outputStream.Seek(0, SeekOrigin.Begin); + return outputStream; + } - var outputStream = new MemoryStream(); - fac.Save(outputStream); - outputStream.Seek(0, SeekOrigin.Begin); - return outputStream; + private static IImageProcessingContext ApplyFilter(IImageProcessingContext fac, ImageFilter filter) + { + switch (filter) + { + case ImageFilter.BlackAndWhite: + return fac.BlackWhite(); + case ImageFilter.GreyScale: + return fac.Grayscale(); + case ImageFilter.HiSatch: + return fac.Saturate(0.7f); + case ImageFilter.Invert: + return fac.Invert(); + case ImageFilter.Lomograph: + return fac.Lomograph(); + case ImageFilter.LoSatch: + return fac.Saturate(0.3f); + case ImageFilter.Polariod: + return fac.Polaroid(); + case ImageFilter.Sepia: + return fac.Sepia(); + case ImageFilter.Comic: + case ImageFilter.Gotham: + throw new NotSupportedException(); + default: + return fac; } } } diff --git a/src/extensions/Wyam.Images/ImageInstruction.cs b/src/extensions/Wyam.Images/ImageInstruction.cs index ad29a70bd..4a1817b1d 100644 --- a/src/extensions/Wyam.Images/ImageInstruction.cs +++ b/src/extensions/Wyam.Images/ImageInstruction.cs @@ -1,7 +1,7 @@ -using ImageProcessor.Imaging.Filters.Photo; +using System; using System.Collections.Generic; using System.Drawing; -using img = ImageProcessor.Imaging; +using SixLabors.ImageSharp.Processing.Transforms; namespace Wyam.Images { @@ -9,8 +9,6 @@ namespace Wyam.Images public class HueInstruction { public int Degrees { get; set; } - - public bool Rotate { get; set; } = false; } public class ImageInstruction @@ -21,7 +19,7 @@ public class ImageInstruction public Size? Constraint { get; set; } - public AnchorPosition AnchorPosition { get; set; } + public AnchorPositionMode AnchorPosition { get; set; } public int? Brightness { get; set; } @@ -47,19 +45,19 @@ public class ImageInstruction public List Filters { get; set; } = new List(); - public Size? GetCropSize() + public SixLabors.Primitives.Size? GetCropSize() { if (Width.HasValue && Height.HasValue) { - return new Size(Width.Value, Height.Value); + return new SixLabors.Primitives.Size(Width.Value, Height.Value); } else if (Width.HasValue) { - return new Size(Width.Value, 0); + return new SixLabors.Primitives.Size(Width.Value, 0); } else if (Height.HasValue) { - return new Size(0, Height.Value); + return new SixLabors.Primitives.Size(0, Height.Value); } return null; @@ -146,39 +144,14 @@ public string GetSuffix() return suffix; } - public IMatrixFilter GetMatrixFilter(ImageFilter filter) + public AnchorPositionMode GetAnchorPosition() { - switch (filter) - { - case ImageFilter.BlackAndWhite: return MatrixFilters.BlackWhite; - case ImageFilter.Comic: return MatrixFilters.Comic; - case ImageFilter.Gotham: return MatrixFilters.Gotham; - case ImageFilter.GreyScale: return MatrixFilters.GreyScale; - case ImageFilter.HiSatch: return MatrixFilters.HiSatch; - case ImageFilter.Invert: return MatrixFilters.Invert; - case ImageFilter.Lomograph: return MatrixFilters.Lomograph; - case ImageFilter.LoSatch: return MatrixFilters.LoSatch; - case ImageFilter.Polariod: return MatrixFilters.Polaroid; - case ImageFilter.Sepia: return MatrixFilters.Sepia; - default: return MatrixFilters.Comic; + if (!Enum.IsDefined(typeof(AnchorPositionMode), AnchorPosition)) + { + return AnchorPositionMode.Center; } - } - public img.AnchorPosition GetAnchorPosition() - { - switch (AnchorPosition) - { - case AnchorPosition.Bottom: return img.AnchorPosition.Bottom; - case AnchorPosition.BottomLeft: return img.AnchorPosition.BottomLeft; - case AnchorPosition.BottomRight: return img.AnchorPosition.BottomRight; - case AnchorPosition.Center: return img.AnchorPosition.Center; - case AnchorPosition.Left: return img.AnchorPosition.Left; - case AnchorPosition.Right: return img.AnchorPosition.Right; - case AnchorPosition.Top: return img.AnchorPosition.Top; - case AnchorPosition.TopLeft: return img.AnchorPosition.TopLeft; - case AnchorPosition.TopRight: return img.AnchorPosition.TopRight; - default: return img.AnchorPosition.Center; - } + return AnchorPosition; } } } diff --git a/src/extensions/Wyam.Images/Wyam.Images.csproj b/src/extensions/Wyam.Images/Wyam.Images.csproj index 8102ecef2..acb68934f 100644 --- a/src/extensions/Wyam.Images/Wyam.Images.csproj +++ b/src/extensions/Wyam.Images/Wyam.Images.csproj @@ -1,6 +1,6 @@  - net462 + netstandard2.0 Wyam is a simple to use, highly modular, and extremely configurable static content generator. This library provides support for manipulating images. Wyam Static StaticContent StaticSite Blog BlogEngine Images ImageProcessor @@ -10,7 +10,7 @@ - +