diff --git a/src/ImageSharp/Processing/Extensions/Transforms/SwizzleExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/SwizzleExtensions.cs
new file mode 100644
index 0000000000..c02b3a00d6
--- /dev/null
+++ b/src/ImageSharp/Processing/Extensions/Transforms/SwizzleExtensions.cs
@@ -0,0 +1,24 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Processing.Processors.Transforms;
+
+namespace SixLabors.ImageSharp.Processing.Extensions.Transforms
+{
+ ///
+ /// Defines extensions that allow the application of swizzle operations on an
+ ///
+ public static class SwizzleExtensions
+ {
+ ///
+ /// Swizzles an image.
+ ///
+ /// The image to swizzle.
+ /// The swizzler function.
+ /// The swizzler function type.
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext Swizzle(this IImageProcessingContext source, TSwizzler swizzler)
+ where TSwizzler : struct, ISwizzler
+ => source.ApplyProcessor(new SwizzleProcessor(swizzler));
+ }
+}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs b/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
new file mode 100644
index 0000000000..0230b7a868
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Transforms/ISwizzler.cs
@@ -0,0 +1,18 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Processing.Processors.Transforms
+{
+ ///
+ /// Encapsulate an algorithm to swizzle pixels in an image.
+ ///
+ public interface ISwizzler
+ {
+ ///
+ /// Applies the swizzle transformation to a given point.
+ ///
+ /// Point to transform.
+ /// Transformed point.
+ Point Transform(Point point);
+ }
+}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
new file mode 100644
index 0000000000..a42a4bf773
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler,TPixel}.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Transforms
+{
+ internal class SwizzleProcessor : ImageProcessor
+ where TSwizzler : struct, ISwizzler
+ where TPixel : unmanaged, IPixel
+ {
+ private readonly TSwizzler swizzler;
+
+ public SwizzleProcessor(Configuration configuration, TSwizzler swizzler, Image source, Rectangle sourceRectangle)
+ : base(configuration, source, sourceRectangle)
+ {
+ this.swizzler = swizzler;
+ }
+
+ ///
+ protected override void OnFrameApply(ImageFrame source)
+ {
+ for (int y = 0; y < source.Height; y++)
+ {
+ var pixelRowSpan = source.GetPixelRowSpan(y);
+ for (int x = 0; x < source.Width; x++)
+ {
+ var newPoint = this.swizzler.Transform(new Point(x, y));
+ }
+ }
+ }
+ }
+}
diff --git a/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
new file mode 100644
index 0000000000..e5b95e673d
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/Transforms/SwizzleProcessor{TSwizzler}.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing.Processors.Transforms
+{
+ ///
+ /// Defines a swizzle operation on an image.
+ ///
+ /// The swizzle function type.
+ public sealed class SwizzleProcessor : IImageProcessor
+ where TSwizzler : struct, ISwizzler
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The swizzler operation.
+ public SwizzleProcessor(TSwizzler swizzler)
+ => this.Swizzler = swizzler;
+
+ ///
+ /// Gets the swizzler operation.
+ ///
+ public TSwizzler Swizzler { get; }
+
+ ///
+ public IImageProcessor CreatePixelSpecificProcessor(Configuration configuration, Image source, Rectangle sourceRectangle)
+ where TPixel : unmanaged, IPixel
+ => new SwizzleProcessor(configuration, this, source, sourceRectangle);
+ }
+}
diff --git a/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs
new file mode 100644
index 0000000000..2862df2127
--- /dev/null
+++ b/tests/ImageSharp.Tests/Processing/Transforms/SwizzleTests.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Six Labors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.Processing.Extensions.Transforms;
+using SixLabors.ImageSharp.Processing.Processors.Transforms;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Processing.Transforms
+{
+ public class SwizzleTests : BaseImageOperationsExtensionTest
+ {
+ private struct InvertXAndYSwizzler : ISwizzler
+ {
+ public Point Transform(Point point) => new Point(point.Y, point.X);
+ }
+
+ [Fact]
+ public void RotateDegreesFloatRotateProcessorWithAnglesSet()
+ {
+ this.operations.Swizzle(default(InvertXAndYSwizzler));
+ SwizzleProcessor processor = this.Verify>();
+
+ // assert that pixels have been changed
+
+ this.operations.Swizzle(default(InvertXAndYSwizzler));
+ SwizzleProcessor processor2 = this.Verify>();
+
+ // assert that pixels have been changed (i.e. back to original)
+ }
+ }
+}