diff --git a/src/ImageSharp/Processing/Delegates/PixelShader.cs b/src/ImageSharp/Processing/Delegates/PixelShader.cs
new file mode 100644
index 000000000..fd051c0e6
--- /dev/null
+++ b/src/ImageSharp/Processing/Delegates/PixelShader.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Numerics;
+
+namespace SixLabors.ImageSharp.Processing.Delegates
+{
+ ///
+ /// A representing a user defined pixel shader.
+ ///
+ /// The target row of pixels to process.
+ /// The , , , and fields map the RGBA channels respectively.
+ public delegate void PixelShader(Span span);
+}
diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs
new file mode 100644
index 000000000..13ac957ec
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Delegates;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors
+{
+ ///
+ /// Applies a user defined pixel shader effect through a given delegate.
+ ///
+ public sealed class DelegatePixelShaderProcessor : IImageProcessor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The user defined pixel shader to use to modify images.
+ ///
+ public DelegatePixelShaderProcessor(PixelShader pixelShader)
+ {
+ this.PixelShader = pixelShader;
+ }
+
+ ///
+ /// Gets the user defined pixel shader.
+ ///
+ public PixelShader PixelShader { get; }
+
+ ///
+ public IImageProcessor CreatePixelSpecificProcessor(Image source, Rectangle sourceRectangle)
+ where TPixel : struct, IPixel
+ {
+ return new DelegatePixelShaderProcessor(this, source, sourceRectangle);
+ }
+ }
+}
diff --git a/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs
new file mode 100644
index 000000000..e6119f2c8
--- /dev/null
+++ b/src/ImageSharp/Processing/Processors/DelegatePixelShaderProcessor{TPixel}.cs
@@ -0,0 +1,66 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Numerics;
+
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Advanced.ParallelUtils;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Delegates;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Processors
+{
+ ///
+ /// Performs simple binary threshold filtering against an image.
+ ///
+ /// The pixel format.
+ internal class DelegatePixelShaderProcessor : ImageProcessor
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// The user defined pixel shader.
+ ///
+ private readonly PixelShader pixelShader;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The defining the processor parameters.
+ /// The source for the current processor instance.
+ /// The source area to process for the current processor instance.
+ public DelegatePixelShaderProcessor(DelegatePixelShaderProcessor definition, Image source, Rectangle sourceRectangle)
+ : base(source, sourceRectangle)
+ {
+ this.pixelShader = definition.PixelShader;
+ }
+
+ ///
+ protected override void OnFrameApply(ImageFrame source)
+ {
+ var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
+ int startX = interest.X;
+ PixelShader pixelShader = this.pixelShader;
+
+ ParallelHelper.IterateRowsWithTempBuffer(
+ interest,
+ this.Configuration,
+ (rows, vectorBuffer) =>
+ {
+ for (int y = rows.Min; y < rows.Max; y++)
+ {
+ Span vectorSpan = vectorBuffer.Span;
+ int length = vectorSpan.Length;
+ Span rowSpan = source.GetPixelRowSpan(y).Slice(startX, length);
+ PixelOperations.Instance.ToVector4(this.Configuration, rowSpan, vectorSpan);
+
+ // Run the user defined pixel shader on the current row of pixels
+ pixelShader(vectorSpan);
+
+ PixelOperations.Instance.FromVector4Destructive(this.Configuration, vectorSpan, rowSpan);
+ }
+ });
+ }
+ }
+}