Browse Source

Simplify filter API further

No need for startY, endY parameters.
af/merge-core
James Jackson-South 10 years ago
parent
commit
4f5fd68f55
  1. 7
      src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs
  2. 4
      src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs
  3. 2
      src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs
  4. 95
      src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs
  5. 15
      src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs
  6. 69
      src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs
  7. 4
      src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs
  8. 6
      src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs
  9. 4
      src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs
  10. 2
      src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs
  11. 2
      src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs
  12. 5
      src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs
  13. 4
      src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs
  14. 5
      src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs
  15. 5
      src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs
  16. 4
      src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs
  17. 4
      src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs
  18. 4
      src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs
  19. 20
      src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs
  20. 6
      src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs
  21. 4
      src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs
  22. 4
      src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs
  23. 8
      src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs
  24. 6
      src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs
  25. 2
      src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs
  26. 2
      src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs
  27. 2
      src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs
  28. 8
      src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs
  29. 4
      src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs
  30. 4
      src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs
  31. 17
      tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs

7
src/ImageSharp/Filters/Processors/Binarization/BinaryThresholdProcessor.cs

@ -56,17 +56,20 @@ namespace ImageSharp.Processors
public TColor LowerColor { get; set; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new GrayscaleBt709Processor<TColor, TPacked>().Apply(source, sourceRectangle);
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float threshold = this.Value;
TColor upper = this.UpperColor;
TColor lower = this.LowerColor;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

4
src/ImageSharp/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs

@ -25,8 +25,10 @@ namespace ImageSharp.Processors
public override bool Compand { get; set; } = true;
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

2
src/ImageSharp/Filters/Processors/Convolution/BoxBlurProcessor.cs

@ -43,7 +43,7 @@ namespace ImageSharp.Processors
public float[][] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new Convolution2PassProcessor<TColor, TPacked>(this.KernelX, this.KernelY).Apply(source, sourceRectangle);
}

95
src/ImageSharp/Filters/Processors/Convolution/Convolution2DProcessor.cs

@ -40,7 +40,7 @@ namespace ImageSharp.Processors
public float[][] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int kernelYHeight = this.KernelY.Length;
int kernelYWidth = this.KernelY[0].Length;
@ -49,11 +49,11 @@ namespace ImageSharp.Processors
int radiusY = kernelYHeight >> 1;
int radiusX = kernelXWidth >> 1;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int maxY = sourceBottom - 1;
int maxY = endY - 1;
int maxX = endX - 1;
TColor[] target = new TColor[source.Width * source.Height];
@ -66,61 +66,58 @@ namespace ImageSharp.Processors
this.ParallelOptions,
y =>
{
if (y >= sourceY && y < sourceBottom)
for (int x = startX; x < endX; x++)
{
for (int x = startX; x < endX; x++)
float rX = 0;
float gX = 0;
float bX = 0;
float rY = 0;
float gY = 0;
float bY = 0;
// Apply each matrix multiplier to the color components for each pixel.
for (int fy = 0; fy < kernelYHeight; fy++)
{
float rX = 0;
float gX = 0;
float bX = 0;
float rY = 0;
float gY = 0;
float bY = 0;
// Apply each matrix multiplier to the color components for each pixel.
for (int fy = 0; fy < kernelYHeight; fy++)
int fyr = fy - radiusY;
int offsetY = y + fyr;
offsetY = offsetY.Clamp(0, maxY);
for (int fx = 0; fx < kernelXWidth; fx++)
{
int fyr = fy - radiusY;
int offsetY = y + fyr;
int fxr = fx - radiusX;
int offsetX = x + fxr;
offsetX = offsetX.Clamp(0, maxX);
Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
float r = currentColor.X;
float g = currentColor.Y;
float b = currentColor.Z;
offsetY = offsetY.Clamp(0, maxY);
if (fy < kernelXHeight)
{
rX += this.KernelX[fy][fx] * r;
gX += this.KernelX[fy][fx] * g;
bX += this.KernelX[fy][fx] * b;
}
for (int fx = 0; fx < kernelXWidth; fx++)
if (fx < kernelYWidth)
{
int fxr = fx - radiusX;
int offsetX = x + fxr;
offsetX = offsetX.Clamp(0, maxX);
Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
float r = currentColor.X;
float g = currentColor.Y;
float b = currentColor.Z;
if (fy < kernelXHeight)
{
rX += this.KernelX[fy][fx] * r;
gX += this.KernelX[fy][fx] * g;
bX += this.KernelX[fy][fx] * b;
}
if (fx < kernelYWidth)
{
rY += this.KernelY[fy][fx] * r;
gY += this.KernelY[fy][fx] * g;
bY += this.KernelY[fy][fx] * b;
}
rY += this.KernelY[fy][fx] * r;
gY += this.KernelY[fy][fx] * g;
bY += this.KernelY[fy][fx] * b;
}
}
}
float red = (float)Math.Sqrt((rX * rX) + (rY * rY));
float green = (float)Math.Sqrt((gX * gX) + (gY * gY));
float blue = (float)Math.Sqrt((bX * bX) + (bY * bY));
float red = (float)Math.Sqrt((rX * rX) + (rY * rY));
float green = (float)Math.Sqrt((gX * gX) + (gY * gY));
float blue = (float)Math.Sqrt((bX * bX) + (bY * bY));
TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W));
targetPixels[x, y] = packed;
}
TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W));
targetPixels[x, y] = packed;
}
});
}

15
src/ImageSharp/Filters/Processors/Convolution/Convolution2PassProcessor.cs

@ -39,7 +39,7 @@ namespace ImageSharp.Processors
public float[][] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float[][] kernelX = this.KernelX;
float[][] kernelY = this.KernelY;
@ -49,8 +49,8 @@ namespace ImageSharp.Processors
TColor[] target = new TColor[width * height];
TColor[] firstPass = new TColor[width * height];
this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, startY, endY, kernelX);
this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, startY, endY, kernelY);
this.ApplyConvolution(width, height, firstPass, source.Pixels, sourceRectangle, kernelX);
this.ApplyConvolution(width, height, target, firstPass, sourceRectangle, kernelY);
source.SetPixels(width, height, target);
}
@ -66,20 +66,19 @@ namespace ImageSharp.Processors
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="startY">The index of the row within the source image to start processing.</param>
/// <param name="endY">The index of the row within the source image to end processing.</param>
/// <param name="kernel">The kernel operator.</param>
private void ApplyConvolution(int width, int height, TColor[] target, TColor[] source, Rectangle sourceRectangle, int startY, int endY, float[][] kernel)
private void ApplyConvolution(int width, int height, TColor[] target, TColor[] source, Rectangle sourceRectangle, float[][] kernel)
{
int kernelHeight = kernel.Length;
int kernelWidth = kernel[0].Length;
int radiusY = kernelHeight >> 1;
int radiusX = kernelWidth >> 1;
int sourceBottom = sourceRectangle.Bottom;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int maxY = sourceBottom - 1;
int maxY = endY - 1;
int maxX = endX - 1;
using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock<TColor, TPacked>(width, height))

69
src/ImageSharp/Filters/Processors/Convolution/ConvolutionProcessor.cs

@ -32,17 +32,17 @@ namespace ImageSharp.Processors
public virtual float[][] KernelXY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float[][] kernelX = this.KernelXY;
int kernelLength = kernelX.GetLength(0);
int radius = kernelLength >> 1;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int maxY = sourceBottom - 1;
int maxY = endY - 1;
int maxX = endX - 1;
TColor[] target = new TColor[source.Width * source.Height];
@ -55,48 +55,45 @@ namespace ImageSharp.Processors
this.ParallelOptions,
y =>
{
if (y >= sourceY && y < sourceBottom)
for (int x = startX; x < endX; x++)
{
for (int x = startX; x < endX; x++)
{
float rX = 0;
float gX = 0;
float bX = 0;
float rX = 0;
float gX = 0;
float bX = 0;
// Apply each matrix multiplier to the color components for each pixel.
for (int fy = 0; fy < kernelLength; fy++)
{
int fyr = fy - radius;
int offsetY = y + fyr;
// Apply each matrix multiplier to the color components for each pixel.
for (int fy = 0; fy < kernelLength; fy++)
{
int fyr = fy - radius;
int offsetY = y + fyr;
offsetY = offsetY.Clamp(0, maxY);
offsetY = offsetY.Clamp(0, maxY);
for (int fx = 0; fx < kernelLength; fx++)
{
int fxr = fx - radius;
int offsetX = x + fxr;
for (int fx = 0; fx < kernelLength; fx++)
{
int fxr = fx - radius;
int offsetX = x + fxr;
offsetX = offsetX.Clamp(0, maxX);
offsetX = offsetX.Clamp(0, maxX);
Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
float r = currentColor.X;
float g = currentColor.Y;
float b = currentColor.Z;
Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
float r = currentColor.X;
float g = currentColor.Y;
float b = currentColor.Z;
rX += kernelX[fy][fx] * r;
gX += kernelX[fy][fx] * g;
bX += kernelX[fy][fx] * b;
}
rX += kernelX[fy][fx] * r;
gX += kernelX[fy][fx] * g;
bX += kernelX[fy][fx] * b;
}
}
float red = rX;
float green = gX;
float blue = bX;
float red = rX;
float green = gX;
float blue = bX;
TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W));
targetPixels[x, y] = packed;
}
TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, sourcePixels[x, y].ToVector4().W));
targetPixels[x, y] = packed;
}
});
}

4
src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DProcessor.cs

@ -28,13 +28,13 @@ namespace ImageSharp.Processors
public bool Grayscale { get; set; }
/// <inheritdoc />
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new Convolution2DProcessor<TColor, TPacked>(this.KernelX, this.KernelY).Apply(source, sourceRectangle);
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.Grayscale)
{

6
src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorCompassProcessor.cs

@ -62,10 +62,12 @@ namespace ImageSharp.Processors
public bool Grayscale { get; set; }
/// <inheritdoc />
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float[][][] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast };
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
@ -136,7 +138,7 @@ namespace ImageSharp.Processors
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.Grayscale)
{

4
src/ImageSharp/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorProcessor.cs

@ -23,13 +23,13 @@ namespace ImageSharp.Processors
public abstract float[][] KernelXY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new ConvolutionProcessor<TColor, TPacked>(this.KernelXY).Apply(source, sourceRectangle);
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.Grayscale)
{

2
src/ImageSharp/Filters/Processors/Convolution/GaussianBlurProcessor.cs

@ -81,7 +81,7 @@ namespace ImageSharp.Processors
public float[][] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new Convolution2PassProcessor<TColor, TPacked>(this.KernelX, this.KernelY).Apply(source, sourceRectangle);
}

2
src/ImageSharp/Filters/Processors/Convolution/GaussianSharpenProcessor.cs

@ -83,7 +83,7 @@ namespace ImageSharp.Processors
public float[][] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
new Convolution2PassProcessor<TColor, TPacked>(this.KernelX, this.KernelY).Apply(source, sourceRectangle);
}

5
src/ImageSharp/Filters/Processors/Effects/AlphaProcessor.cs

@ -37,9 +37,12 @@ namespace ImageSharp.Processors
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float alpha = this.Value / 100F;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

4
src/ImageSharp/Filters/Processors/Effects/BackgroundColorProcessor.cs

@ -38,8 +38,10 @@ namespace ImageSharp.Processors
public TColor Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

5
src/ImageSharp/Filters/Processors/Effects/BrightnessProcessor.cs

@ -37,9 +37,12 @@ namespace ImageSharp.Processors
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float brightness = this.Value / 100F;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

5
src/ImageSharp/Filters/Processors/Effects/ContrastProcessor.cs

@ -37,9 +37,12 @@ namespace ImageSharp.Processors
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
float contrast = (100F + this.Value) / 100F;
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1);

4
src/ImageSharp/Filters/Processors/Effects/InvertProcessor.cs

@ -19,8 +19,10 @@ namespace ImageSharp.Processors
where TPacked : struct
{
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
Vector3 inverseVector = Vector3.One;

4
src/ImageSharp/Filters/Processors/Effects/OilPaintingProcessor.cs

@ -48,8 +48,10 @@ namespace ImageSharp.Processors
public int BrushSize { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int radius = this.BrushSize >> 1;

4
src/ImageSharp/Filters/Processors/Effects/PixelateProcessor.cs

@ -37,8 +37,10 @@ namespace ImageSharp.Processors
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
int size = this.Value;

20
src/ImageSharp/Filters/Processors/ImageFilteringProcessor.cs

@ -21,9 +21,9 @@ namespace ImageSharp.Processors
{
try
{
this.OnApply(source, sourceRectangle);
this.BeforeApply(source, sourceRectangle);
this.Apply(source, sourceRectangle, sourceRectangle.Y, sourceRectangle.Bottom);
this.OnApply(source, sourceRectangle);
this.AfterApply(source, sourceRectangle);
}
@ -34,27 +34,25 @@ namespace ImageSharp.Processors
}
/// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase{TColor, TPacked}"/> at the specified location
/// and with the specified size.
/// This method is called before the process is applied to prepare the processor.
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="startY">The index of the row within the source image to start processing.</param>
/// <param name="endY">The index of the row within the source image to end processing.</param>
protected abstract void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY);
protected virtual void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
}
/// <summary>
/// This method is called before the process is applied to prepare the processor.
/// Applies the process to the specified portion of the specified <see cref="ImageBase{TColor, TPacked}"/> at the specified location
/// and with the specified size.
/// </summary>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
protected virtual void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
}
protected abstract void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle);
/// <summary>
/// This method is called after the process is applied to prepare the processor.

6
src/ImageSharp/Filters/Processors/Overlays/BlendProcessor.cs

@ -55,7 +55,7 @@ namespace ImageSharp.Processors
public Point Location { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.Image.Bounds.Size != this.Size)
{
@ -66,8 +66,8 @@ namespace ImageSharp.Processors
Rectangle bounds = this.Image.Bounds;
int minX = Math.Max(this.Location.X, sourceRectangle.X);
int maxX = Math.Min(this.Location.X + bounds.Width, sourceRectangle.Width);
int minY = Math.Max(this.Location.Y, startY);
int maxY = Math.Min(this.Location.Y + bounds.Height, endY);
int minY = Math.Max(this.Location.Y, sourceRectangle.Y);
int maxY = Math.Min(this.Location.Y + bounds.Height, sourceRectangle.Bottom);
float alpha = this.Alpha / 100F;

4
src/ImageSharp/Filters/Processors/Overlays/GlowProcessor.cs

@ -39,8 +39,10 @@ namespace ImageSharp.Processors
public float Radius { get; set; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
TColor glowColor = this.GlowColor;

4
src/ImageSharp/Filters/Processors/Overlays/VignetteProcessor.cs

@ -44,8 +44,10 @@ namespace ImageSharp.Processors
public float RadiusY { get; set; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int startY = sourceRectangle.Y;
int endY = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
TColor vignetteColor = this.VignetteColor;

8
src/ImageSharp/Filters/Processors/Transforms/CompandingResizeProcessor.cs

@ -48,7 +48,7 @@ namespace ImageSharp.Processors
public override bool Compand { get; set; } = true;
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
// Jump out, we'll deal with that later.
if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle)
@ -56,12 +56,10 @@ namespace ImageSharp.Processors
return;
}
// Reset the values as the rectangle can be altered by ResizeRectangle.
startY = this.ResizeRectangle.Y;
endY = this.ResizeRectangle.Bottom;
int width = this.Width;
int height = this.Height;
int startY = this.ResizeRectangle.Y;
int endY = this.ResizeRectangle.Bottom;
int startX = this.ResizeRectangle.X;
int endX = this.ResizeRectangle.Right;

6
src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs

@ -32,15 +32,15 @@ namespace ImageSharp.Processors
public Rectangle CropRectangle { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.CropRectangle == sourceRectangle)
{
return;
}
int minY = Math.Max(this.CropRectangle.Y, startY);
int maxY = Math.Min(this.CropRectangle.Bottom, endY);
int minY = Math.Max(this.CropRectangle.Y, sourceRectangle.Y);
int maxY = Math.Min(this.CropRectangle.Bottom, sourceRectangle.Bottom);
int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);

2
src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs

@ -34,7 +34,7 @@ namespace ImageSharp.Processors
public float Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
ImageBase<TColor, TPacked> temp = new Image<TColor, TPacked>(source.Width, source.Height);
temp.ClonePixels(source.Width, source.Height, source.Pixels);

2
src/ImageSharp/Filters/Processors/Transforms/FlipProcessor.cs

@ -32,7 +32,7 @@ namespace ImageSharp.Processors
public FlipType FlipType { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
switch (this.FlipType)
{

2
src/ImageSharp/Filters/Processors/Transforms/ResamplingWeightedProcessor.cs

@ -69,7 +69,7 @@ namespace ImageSharp.Processors
protected Weights[] VerticalWeights { get; set; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (!(this.Sampler is NearestNeighborResampler))
{

8
src/ImageSharp/Filters/Processors/Transforms/ResizeProcessor.cs

@ -47,7 +47,7 @@ namespace ImageSharp.Processors
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
// Jump out, we'll deal with that later.
if (source.Width == this.Width && source.Height == this.Height && sourceRectangle == this.ResizeRectangle)
@ -55,12 +55,10 @@ namespace ImageSharp.Processors
return;
}
// Reset the values as the rectangle can be altered by ResizeRectangle.
startY = this.ResizeRectangle.Y;
endY = this.ResizeRectangle.Bottom;
int width = this.Width;
int height = this.Height;
int startY = this.ResizeRectangle.Y;
int endY = this.ResizeRectangle.Bottom;
int startX = this.ResizeRectangle.X;
int endX = this.ResizeRectangle.Right;

4
src/ImageSharp/Filters/Processors/Transforms/RotateProcessor.cs

@ -34,7 +34,7 @@ namespace ImageSharp.Processors
public bool Expand { get; set; } = true;
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
if (this.OptimizedApply(source))
{
@ -70,7 +70,7 @@ namespace ImageSharp.Processors
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
const float Epsilon = .0001F;

4
src/ImageSharp/Filters/Processors/Transforms/SkewProcessor.cs

@ -39,7 +39,7 @@ namespace ImageSharp.Processors
public bool Expand { get; set; } = true;
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
int height = this.CanvasRectangle.Height;
int width = this.CanvasRectangle.Width;
@ -70,7 +70,7 @@ namespace ImageSharp.Processors
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
protected override void BeforeApply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle)
{
this.processMatrix = Point.CreateSkew(new Point(0, 0), -this.AngleX, -this.AngleY);
if (this.Expand)

17
tests/ImageSharp.Tests/Processors/Filters/OilPaintTest.cs

@ -15,8 +15,8 @@ namespace ImageSharp.Tests
public static readonly TheoryData<Tuple<int, int>> OilPaintValues
= new TheoryData<Tuple<int, int>>
{
new Tuple<int, int>(15,10),
new Tuple<int, int>(6,5)
new Tuple<int, int>(15, 10),
new Tuple<int, int>(6, 5)
};
[Theory]
@ -32,8 +32,11 @@ namespace ImageSharp.Tests
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.OilPaint(value.Item1, value.Item2)
.Save(output);
if (image.Width > value.Item2 && image.Height > value.Item2)
{
image.OilPaint(value.Item1, value.Item2)
.Save(output);
}
}
}
}
@ -51,8 +54,10 @@ namespace ImageSharp.Tests
using (FileStream output = File.OpenWrite($"{path}/{filename}"))
{
image.OilPaint(value.Item1, value.Item2, new Rectangle(10, 10, image.Width / 2, image.Height / 2))
.Save(output);
if (image.Width > value.Item2 && image.Height > value.Item2)
{
image.OilPaint(value.Item1, value.Item2, new Rectangle(10, 10, image.Width / 2, image.Height / 2)).Save(output);
}
}
}
}

Loading…
Cancel
Save