Browse Source

Merge pull request #1145 from SixLabors/js/fix-detect-edges

Fix edge detection and reenable entropy crop tests
pull/1152/head
James Jackson-South 6 years ago
committed by GitHub
parent
commit
7ea5c4e208
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs
  2. 5
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor{TPixel}.cs
  3. 5
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs
  4. 5
      src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorProcessor{TPixel}.cs
  5. 67
      src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs
  6. 11
      tests/ImageSharp.Tests/Processing/Processors/Transforms/EntropyCropTest.cs
  7. 2
      tests/Images/External

6
src/ImageSharp/Processing/Processors/Convolution/ConvolutionProcessor{TPixel}.cs

@ -58,9 +58,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
var operation = new RowOperation(interest, targetPixels, source.PixelBuffer, this.KernelXY, this.Configuration, this.PreserveAlpha);
ParallelRowIterator.IterateRows<RowOperation, Vector4>(
this.Configuration,
interest,
in operation);
this.Configuration,
interest,
in operation);
Buffer2D<TPixel>.SwapOrCopyContent(source.PixelBuffer, targetPixels);
}

5
src/ImageSharp/Processing/Processors/Convolution/EdgeDetector2DProcessor{TPixel}.cs

@ -52,6 +52,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <inheritdoc/>
protected override void BeforeImageApply()
{
using (IImageProcessor<TPixel> opaque = new OpaqueProcessor<TPixel>(this.Configuration, this.Source, this.SourceRectangle))
{
opaque.Execute();
}
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).Execute(this.Configuration, this.Source, this.SourceRectangle);

5
src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorCompassProcessor{TPixel}.cs

@ -40,6 +40,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <inheritdoc/>
protected override void BeforeImageApply()
{
using (IImageProcessor<TPixel> opaque = new OpaqueProcessor<TPixel>(this.Configuration, this.Source, this.SourceRectangle))
{
opaque.Execute();
}
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).Execute(this.Configuration, this.Source, this.SourceRectangle);

5
src/ImageSharp/Processing/Processors/Convolution/EdgeDetectorProcessor{TPixel}.cs

@ -43,6 +43,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
/// <inheritdoc/>
protected override void BeforeImageApply()
{
using (IImageProcessor<TPixel> opaque = new OpaqueProcessor<TPixel>(this.Configuration, this.Source, this.SourceRectangle))
{
opaque.Execute();
}
if (this.Grayscale)
{
new GrayscaleBt709Processor(1F).Execute(this.Configuration, this.Source, this.SourceRectangle);

67
src/ImageSharp/Processing/Processors/Filters/OpaqueProcessor{TPixel}.cs

@ -0,0 +1,67 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Processing.Processors.Filters
{
internal sealed class OpaqueProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
public OpaqueProcessor(
Configuration configuration,
Image<TPixel> source,
Rectangle sourceRectangle)
: base(configuration, source, sourceRectangle)
{
}
protected override void OnFrameApply(ImageFrame<TPixel> source)
{
var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds());
var operation = new OpaqueRowOperation(this.Configuration, source, interest);
ParallelRowIterator.IterateRows<OpaqueRowOperation, Vector4>(this.Configuration, interest, in operation);
}
private readonly struct OpaqueRowOperation : IRowOperation<Vector4>
{
private readonly Configuration configuration;
private readonly ImageFrame<TPixel> target;
private readonly Rectangle bounds;
[MethodImpl(InliningOptions.ShortMethod)]
public OpaqueRowOperation(
Configuration configuration,
ImageFrame<TPixel> target,
Rectangle bounds)
{
this.configuration = configuration;
this.target = target;
this.bounds = bounds;
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void Invoke(int y, Span<Vector4> span)
{
Span<TPixel> targetRowSpan = this.target.GetPixelRowSpan(y).Slice(this.bounds.X);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, targetRowSpan.Slice(0, span.Length), span, PixelConversionModifiers.Scale);
ref Vector4 baseRef = ref MemoryMarshal.GetReference(span);
for (int x = 0; x < this.bounds.Width; x++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, x);
v.W = 1F;
}
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, targetRowSpan, PixelConversionModifiers.Scale);
}
}
}
}

11
tests/ImageSharp.Tests/Processing/Processors/Transforms/EntropyCropTest.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -25,15 +25,6 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
public void EntropyCrop<TPixel>(TestImageProvider<TPixel> provider, float value)
where TPixel : unmanaged, IPixel<TPixel>
{
// The result dimensions of EntropyCrop may differ on .NET Core 3.1 because of unstable edge detection results.
// TODO: Re-enable this test case if we manage to improve stability.
#if SUPPORTS_RUNTIME_INTRINSICS
if (provider.SourceFileOrDescription.Contains(TestImages.Png.Ducky))
{
return;
}
#endif
provider.RunValidatingProcessorTest(x => x.EntropyCrop(value), value, appendPixelTypeToFileName: false);
}
}

2
tests/Images/External

@ -1 +1 @@
Subproject commit 1fea1ceab89e87cc5f11376fa46164d3d27566c0
Subproject commit d809551931858cd3873bad49d2fe915fddff7a26
Loading…
Cancel
Save