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];
+ }
}
}
});