From b902246a29ce163256b8b37e436e96ac387f65e9 Mon Sep 17 00:00:00 2001 From: SLane35 Date: Thu, 9 May 2019 02:46:40 +0300 Subject: [PATCH 1/3] Update Readme (#905) A few minor grammatical corrections. --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ceb28564b9..515fc71969 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Designed to democratize image processing, ImageSharp brings you an incredibly po Compared to `System.Drawing` we have been able to develop something much more flexible, easier to code against, and much, much less prone to memory leaks. Gone are system-wide process-locks; ImageSharp images are thread-safe and fully supported in web environments. -Built against .NET Standard 1.3 ImageSharp can be used in device, cloud, and embedded/IoT scenarios. +Built against .NET Standard 1.3, ImageSharp can be used in device, cloud, and embedded/IoT scenarios. ### Documentation For all SixLabors projects, including ImageSharp: @@ -41,15 +41,15 @@ Install stable releases via Nuget; development releases are available via MyGet. The **ImageSharp** library is made up of multiple packages: - **SixLabors.ImageSharp** - - Contains the generic `Image` class, PixelFormats, Primitives, Configuration, and other core functionality. - - The `IImageFormat` interface, Jpeg, Png, Bmp, and Gif formats. - - Transform methods like Resize, Crop, Skew, Rotate - Anything that alters the dimensions of the image. - - Non-transform methods like Gaussian Blur, Pixelate, Edge Detection - Anything that maintains the original image dimensions. + - Contains the generic `Image` class, PixelFormats, Primitives, Configuration, and other core functionality + - The `IImageFormat` interface, Jpeg, Png, Bmp, and Gif formats + - Transform methods like Resize, Crop, Skew, Rotate - anything that alters the dimensions of the image + - Non-transform methods like Gaussian Blur, Pixelate, Edge Detection - anything that maintains the original image dimensions - **SixLabors.ImageSharp.Drawing** - - Brushes and various drawing algorithms, including drawing images. + - Brushes and various drawing algorithms, including drawing images - Various vector drawing methods for drawing paths, polygons etc. - - Text drawing. + - Text drawing ### Build Status @@ -117,7 +117,7 @@ Alternatively, you can work from command line and/or with a lightweight editor o - [Visual Studio Code](https://code.visualstudio.com/) with [C# Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) - [.NET Core](https://www.microsoft.com/net/core#linuxubuntu) -To clone ImageSharp locally click the "Clone in Windows" button above or run the following git commands. +To clone ImageSharp locally, click the "Clone in Windows" button above or run the following git commands: ```bash git clone https://github.com/SixLabors/ImageSharp From a7720e53cbe9570fc56e251a44aa96b574a8d34c Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 9 May 2019 22:18:18 +0200 Subject: [PATCH 2/3] verbose naming for Histogram Equalization stuff + make it public --- ... AdaptiveHistogramEqualizationProcessor.cs} | 18 +++++++++++++----- ...eHistogramEqualizationProcessor{TPixel}.cs} | 6 +++--- ...ogramEqualizationSlidingWindowProcessor.cs} | 16 ++++++++++++---- ...alizationSlidingWindowProcessor{TPixel}.cs} | 6 +++--- .../GlobalHistogramEqualizationProcessor.cs | 8 +++++++- .../HistogramEqualizationProcessor.cs | 6 +++--- 6 files changed, 41 insertions(+), 19 deletions(-) rename src/ImageSharp/Processing/Processors/Normalization/{AdaptiveHistEqualizationProcessor.cs => AdaptiveHistogramEqualizationProcessor.cs} (76%) rename src/ImageSharp/Processing/Processors/Normalization/{AdaptiveHistEqualizationProcessor{TPixel}.cs => AdaptiveHistogramEqualizationProcessor{TPixel}.cs} (98%) rename src/ImageSharp/Processing/Processors/Normalization/{AdaptiveHistEqualizationSWProcessor.cs => AdaptiveHistogramEqualizationSlidingWindowProcessor.cs} (72%) rename src/ImageSharp/Processing/Processors/Normalization/{AdaptiveHistEqualizationSWProcessor{TPixel}.cs => AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs} (98%) diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor.cs similarity index 76% rename from src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs rename to src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor.cs index 4fd0f853d0..ad27ae020c 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor.cs @@ -7,17 +7,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// Applies an adaptive histogram equalization to the image. The image is split up in tiles. For each tile a cumulative distribution function (cdf) is calculated. /// To calculate the final equalized pixel value, the cdf value of four adjacent tiles will be interpolated. /// - internal class AdaptiveHistEqualizationProcessor : HistogramEqualizationProcessor + public class AdaptiveHistogramEqualizationProcessor : HistogramEqualizationProcessor { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// or 65536 for 16-bit grayscale images. /// Indicating whether to clip the histogram bins at a specific value. /// Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value. /// The number of tiles the image is split into (horizontal and vertically). Minimum value is 2. Maximum value is 100. - public AdaptiveHistEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int numberOfTiles) + public AdaptiveHistogramEqualizationProcessor( + int luminanceLevels, + bool clipHistogram, + float clipLimitPercentage, + int numberOfTiles) : base(luminanceLevels, clipHistogram, clipLimitPercentage) { this.NumberOfTiles = numberOfTiles; @@ -31,7 +35,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// public override IImageProcessor CreatePixelSpecificProcessor() { - return new AdaptiveHistEqualizationProcessor(this.LuminanceLevels, this.ClipHistogram, this.ClipLimitPercentage, this.NumberOfTiles); + return new AdaptiveHistogramEqualizationProcessor( + this.LuminanceLevels, + this.ClipHistogram, + this.ClipLimitPercentage, + this.NumberOfTiles); } } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs similarity index 98% rename from src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs index 930c4010fa..333444eb39 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs @@ -21,18 +21,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// To calculate the final equalized pixel value, the cdf value of four adjacent tiles will be interpolated. /// /// The pixel format. - internal class AdaptiveHistEqualizationProcessor : HistogramEqualizationProcessor + internal class AdaptiveHistogramEqualizationProcessor : HistogramEqualizationProcessor where TPixel : struct, IPixel { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// or 65536 for 16-bit grayscale images. /// Indicating whether to clip the histogram bins at a specific value. /// Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value. /// The number of tiles the image is split into (horizontal and vertically). Minimum value is 2. Maximum value is 100. - public AdaptiveHistEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) + public AdaptiveHistogramEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) : base(luminanceLevels, clipHistogram, clipLimitPercentage) { Guard.MustBeGreaterThanOrEqualTo(tiles, 2, nameof(tiles)); diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor.cs similarity index 72% rename from src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor.cs rename to src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor.cs index cd4a9644ff..36f798975a 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor.cs @@ -6,17 +6,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// /// Applies an adaptive histogram equalization to the image using an sliding window approach. /// - internal class AdaptiveHistEqualizationSWProcessor : HistogramEqualizationProcessor + public class AdaptiveHistogramEqualizationSlidingWindowProcessor : HistogramEqualizationProcessor { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// or 65536 for 16-bit grayscale images. /// Indicating whether to clip the histogram bins at a specific value. /// Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value. /// The number of tiles the image is split into (horizontal and vertically). Minimum value is 2. Maximum value is 100. - public AdaptiveHistEqualizationSWProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int numberOfTiles) + public AdaptiveHistogramEqualizationSlidingWindowProcessor( + int luminanceLevels, + bool clipHistogram, + float clipLimitPercentage, + int numberOfTiles) : base(luminanceLevels, clipHistogram, clipLimitPercentage) { this.NumberOfTiles = numberOfTiles; @@ -30,7 +34,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// public override IImageProcessor CreatePixelSpecificProcessor() { - return new AdaptiveHistEqualizationSWProcessor(this.LuminanceLevels, this.ClipHistogram, this.ClipLimitPercentage, this.NumberOfTiles); + return new AdaptiveHistogramEqualizationSlidingWindowProcessor( + this.LuminanceLevels, + this.ClipHistogram, + this.ClipLimitPercentage, + this.NumberOfTiles); } } } \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs similarity index 98% rename from src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor{TPixel}.cs rename to src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs index 3584b1a88b..40e2d41d9b 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs @@ -20,18 +20,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// Applies an adaptive histogram equalization to the image using an sliding window approach. /// /// The pixel format. - internal class AdaptiveHistEqualizationSWProcessor : HistogramEqualizationProcessor + internal class AdaptiveHistogramEqualizationSlidingWindowProcessor : HistogramEqualizationProcessor where TPixel : struct, IPixel { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// or 65536 for 16-bit grayscale images. /// Indicating whether to clip the histogram bins at a specific value. /// Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value. /// The number of tiles the image is split into (horizontal and vertically). Minimum value is 2. Maximum value is 100. - public AdaptiveHistEqualizationSWProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) + public AdaptiveHistogramEqualizationSlidingWindowProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) : base(luminanceLevels, clipHistogram, clipLimitPercentage) { Guard.MustBeGreaterThanOrEqualTo(tiles, 2, nameof(tiles)); diff --git a/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs index 62e0185950..9af2c8352b 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs @@ -6,8 +6,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// /// Defines a global histogram equalization applicable to an . /// - internal class GlobalHistogramEqualizationProcessor : HistogramEqualizationProcessor + public class GlobalHistogramEqualizationProcessor : HistogramEqualizationProcessor { + /// + /// Initializes a new instance of the class. + /// + /// The number of luminance levels. + /// A value indicating whether to clip the histogram bins at a specific value. + /// The histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value. public GlobalHistogramEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage) : base(luminanceLevels, clipHistogram, clipLimitPercentage) { diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs index 4aad1f564e..b1d12f8478 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs @@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// /// Defines a processor that normalizes the histogram of an image. /// - internal abstract class HistogramEqualizationProcessor : IImageProcessor + public abstract class HistogramEqualizationProcessor : IImageProcessor { /// /// Initializes a new instance of the class. @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization break; case HistogramEqualizationMethod.AdaptiveTileInterpolation: - processor = new AdaptiveHistEqualizationProcessor( + processor = new AdaptiveHistogramEqualizationProcessor( options.LuminanceLevels, options.ClipHistogram, options.ClipLimitPercentage, @@ -71,7 +71,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization break; case HistogramEqualizationMethod.AdaptiveSlidingWindow: - processor = new AdaptiveHistEqualizationSWProcessor( + processor = new AdaptiveHistogramEqualizationSlidingWindowProcessor( options.LuminanceLevels, options.ClipHistogram, options.ClipLimitPercentage, From b92731896daab0ff627c7a8e65b07a4ec8f3bffb Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 9 May 2019 22:32:27 +0200 Subject: [PATCH 3/3] formatting --- .../AffineTransformProcessor{TPixel}.cs | 21 ++++-- .../Transforms/AutoOrientProcessor{TPixel}.cs | 5 +- .../ProjectiveTransformProcessor{TPixel}.cs | 27 ++++++-- .../Transforms/RotateProcessor{TPixel}.cs | 68 +++++++++++-------- 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs index e57ce826bd..5a043cb207 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor{TPixel}.cs @@ -25,18 +25,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms this.Definition = definition; } + protected AffineTransformProcessor Definition { get; } + private Size TargetDimensions => this.Definition.TargetDimensions; private Matrix3x2 TransformMatrix => this.Definition.TransformMatrix; - protected AffineTransformProcessor Definition { get; } - /// protected override Image CreateDestination(Image source, Rectangle sourceRectangle) { // We will always be creating the clone even for mutate because we may need to resize the canvas - IEnumerable> frames = - source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions, x.Metadata.DeepClone())); + IEnumerable> frames = source.Frames.Select( + x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions, x.Metadata.DeepClone())); // Use the overload to prevent an extra frame being added return new Image(source.GetConfiguration(), source.Metadata.DeepClone(), frames); @@ -111,10 +111,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Use the single precision position to calculate correct bounding pixels // otherwise we get rogue pixels outside of the bounds. var point = Vector2.Transform(new Vector2(x, y), matrix); - kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); + kernel.Convolve( + point, + x, + ref ySpanRef, + ref xSpanRef, + source.PixelBuffer, + vectorSpan); } - PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4Destructive( + configuration, + vectorSpan, + targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/AutoOrientProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/AutoOrientProcessor{TPixel}.cs index 257c223dc4..8b3ec8690e 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/AutoOrientProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/AutoOrientProcessor{TPixel}.cs @@ -61,7 +61,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } /// - protected override void OnFrameApply(ImageFrame sourceBase, Rectangle sourceRectangle, Configuration config) + protected override void OnFrameApply( + ImageFrame sourceBase, + Rectangle sourceRectangle, + Configuration config) { // All processing happens at the image level within BeforeImageApply(); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs index e6d885803b..ab07040f71 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor{TPixel}.cs @@ -33,15 +33,23 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms protected override Image CreateDestination(Image source, Rectangle sourceRectangle) { // We will always be creating the clone even for mutate because we may need to resize the canvas - IEnumerable> frames = - source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions.Width, this.TargetDimensions.Height, x.Metadata.DeepClone())); + IEnumerable> frames = source.Frames.Select( + x => new ImageFrame( + source.GetConfiguration(), + this.TargetDimensions.Width, + this.TargetDimensions.Height, + x.Metadata.DeepClone())); // Use the overload to prevent an extra frame being added return new Image(source.GetConfiguration(), source.Metadata.DeepClone(), frames); } /// - protected override void OnFrameApply(ImageFrame source, ImageFrame destination, Rectangle sourceRectangle, Configuration configuration) + protected override void OnFrameApply( + ImageFrame source, + ImageFrame destination, + Rectangle sourceRectangle, + Configuration configuration) { Matrix4x4 transformMatrix = this.definition.TransformMatrix; @@ -110,10 +118,19 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Use the single precision position to calculate correct bounding pixels // otherwise we get rogue pixels outside of the bounds. Vector2 point = TransformUtils.ProjectiveTransform2D(x, y, matrix); - kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); + kernel.Convolve( + point, + x, + ref ySpanRef, + ref xSpanRef, + source.PixelBuffer, + vectorSpan); } - PixelOperations.Instance.FromVector4Destructive(configuration, vectorSpan, targetRowSpan); + PixelOperations.Instance.FromVector4Destructive( + configuration, + vectorSpan, + targetRowSpan); } }); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs index aac6f65148..252cb77aba 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/RotateProcessor{TPixel}.cs @@ -27,18 +27,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms private float Degrees { get; } /// - protected override void OnFrameApply(ImageFrame source, ImageFrame destination, Rectangle sourceRectangle, Configuration configuration) - { - if (this.OptimizedApply(source, destination, configuration)) - { - return; - } - - base.OnFrameApply(source, destination, sourceRectangle, configuration); - } - - /// - protected override void AfterImageApply(Image source, Image destination, Rectangle sourceRectangle) + protected override void AfterImageApply( + Image source, + Image destination, + Rectangle sourceRectangle) { ExifProfile profile = destination.Metadata.ExifProfile; if (profile is null) @@ -57,6 +49,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms base.AfterImageApply(source, destination, sourceRectangle); } + /// + protected override void OnFrameApply( + ImageFrame source, + ImageFrame destination, + Rectangle sourceRectangle, + Configuration configuration) + { + if (this.OptimizedApply(source, destination, configuration)) + { + return; + } + + base.OnFrameApply(source, destination, sourceRectangle, configuration); + } + /// /// Wraps a given angle in degrees so that it falls withing the 0-360 degree range /// @@ -83,7 +90,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The /// - private bool OptimizedApply(ImageFrame source, ImageFrame destination, Configuration configuration) + private bool OptimizedApply( + ImageFrame source, + ImageFrame destination, + Configuration configuration) { // Wrap the degrees to keep within 0-360 so we can apply optimizations when possible. float degrees = WrapDegrees(this.Degrees); @@ -117,16 +127,15 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } /// - /// Rotates the image 270 degrees clockwise at the centre point. + /// Rotates the image 180 degrees clockwise at the centre point. /// /// The source image. /// The destination image. /// The configuration. - private void Rotate270(ImageFrame source, ImageFrame destination, Configuration configuration) + private void Rotate180(ImageFrame source, ImageFrame destination, Configuration configuration) { int width = source.Width; int height = source.Height; - Rectangle destinationBounds = destination.Bounds(); ParallelHelper.IterateRows( source.Bounds(), @@ -136,31 +145,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int y = rows.Min; y < rows.Max; y++) { Span sourceRow = source.GetPixelRowSpan(y); + Span targetRow = destination.GetPixelRowSpan(height - y - 1); + for (int x = 0; x < width; x++) { - int newX = height - y - 1; - newX = height - newX - 1; - int newY = width - x - 1; - - if (destinationBounds.Contains(newX, newY)) - { - destination[newX, newY] = sourceRow[x]; - } + targetRow[width - x - 1] = sourceRow[x]; } } }); } /// - /// Rotates the image 180 degrees clockwise at the centre point. + /// Rotates the image 270 degrees clockwise at the centre point. /// /// The source image. /// The destination image. /// The configuration. - private void Rotate180(ImageFrame source, ImageFrame destination, Configuration configuration) + private void Rotate270(ImageFrame source, ImageFrame destination, Configuration configuration) { int width = source.Width; int height = source.Height; + Rectangle destinationBounds = destination.Bounds(); ParallelHelper.IterateRows( source.Bounds(), @@ -170,11 +175,16 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int y = rows.Min; y < rows.Max; y++) { Span sourceRow = source.GetPixelRowSpan(y); - Span targetRow = destination.GetPixelRowSpan(height - y - 1); - for (int x = 0; x < width; x++) { - targetRow[width - x - 1] = sourceRow[x]; + int newX = height - y - 1; + newX = height - newX - 1; + int newY = width - x - 1; + + if (destinationBounds.Contains(newX, newY)) + { + destination[newX, newY] = sourceRow[x]; + } } } });