From a0dc40a0231e953a6a1710a2f79483824583b4ed Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 8 Dec 2016 22:57:07 +1100 Subject: [PATCH] Move Entropy Crop --- .../Transforms/EntropyCropProcessor.cs | 58 ++++++++++ .../Transforms/EntropyCrop.cs | 3 +- .../Transforms/EntropyCropProcessor.cs | 107 ------------------ 3 files changed, 60 insertions(+), 108 deletions(-) create mode 100644 src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs rename src/ImageSharp/{Samplers => Filters}/Transforms/EntropyCrop.cs (87%) delete mode 100644 src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs diff --git a/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs new file mode 100644 index 0000000000..6a5fd867af --- /dev/null +++ b/src/ImageSharp/Filters/Processors/Transforms/EntropyCropProcessor.cs @@ -0,0 +1,58 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp.Processors +{ + /// + /// Provides methods to allow the cropping of an image to preserve areas of highest + /// entropy. + /// + /// The pixel format. + /// The packed format. uint, long, float. + public class EntropyCropProcessor : ImageFilteringProcessor + where TColor : struct, IPackedPixel + where TPacked : struct + { + /// + /// Initializes a new instance of the class. + /// + /// The threshold to split the image. Must be between 0 and 1. + /// + /// is less than 0 or is greater than 1. + /// + public EntropyCropProcessor(float threshold) + { + Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); + this.Value = threshold; + } + + /// + /// Gets the threshold value. + /// + public float Value { get; } + + /// + protected override void Apply(ImageBase source, Rectangle sourceRectangle, int startY, int endY) + { + ImageBase temp = new Image(source.Width, source.Height); + + // Detect the edges. + new SobelProcessor().Apply(temp, source, sourceRectangle); + + // Apply threshold binarization filter. + new BinaryThresholdProcessor(this.Value).Apply(temp, sourceRectangle); + + // Search for the first white pixels + Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); + + if (rectangle == sourceRectangle) + { + return; + } + + new CropProcessor(rectangle).Apply(source, sourceRectangle); + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Transforms/EntropyCrop.cs b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs similarity index 87% rename from src/ImageSharp/Samplers/Transforms/EntropyCrop.cs rename to src/ImageSharp/Filters/Transforms/EntropyCrop.cs index 28a2ebf486..17fb109eed 100644 --- a/src/ImageSharp/Samplers/Transforms/EntropyCrop.cs +++ b/src/ImageSharp/Filters/Transforms/EntropyCrop.cs @@ -25,7 +25,8 @@ namespace ImageSharp where TPacked : struct { EntropyCropProcessor processor = new EntropyCropProcessor(threshold); - return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor); + return source.Process(source.Bounds, processor); + // return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor); } } } \ No newline at end of file diff --git a/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs b/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs deleted file mode 100644 index f9c8b2ae46..0000000000 --- a/src/ImageSharp/Samplers/Processors/Transforms/EntropyCropProcessor.cs +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageSharp.Processors -{ - using System; - using System.Threading.Tasks; - - /// - /// Provides methods to allow the cropping of an image to preserve areas of highest - /// entropy. - /// - /// The pixel format. - /// The packed format. uint, long, float. - public class EntropyCropProcessor : ImageSamplingProcessor - where TColor : struct, IPackedPixel - where TPacked : struct - { - /// - /// The rectangle for cropping - /// - private Rectangle cropRectangle; - - /// - /// Initializes a new instance of the class. - /// - /// The threshold to split the image. Must be between 0 and 1. - /// - /// is less than 0 or is greater than 1. - /// - public EntropyCropProcessor(float threshold) - { - Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); - this.Value = threshold; - } - - /// - /// Gets the threshold value. - /// - public float Value { get; } - - /// - public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - { - // Jump out, we'll deal with that later. - if (source.Bounds == target.Bounds) - { - return; - } - - int targetY = this.cropRectangle.Y; - int targetBottom = this.cropRectangle.Bottom; - int startX = this.cropRectangle.X; - int endX = this.cropRectangle.Right; - - int minY = Math.Max(targetY, startY); - int maxY = Math.Min(targetBottom, endY); - - using (PixelAccessor sourcePixels = source.Lock()) - using (PixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - minY, - maxY, - this.ParallelOptions, - y => - { - for (int x = startX; x < endX; x++) - { - targetPixels[x - startX, y - targetY] = sourcePixels[x, y]; - } - }); - } - } - - /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - ImageBase temp = new Image(source.Width, source.Height); - - // Detect the edges. - new SobelProcessor().Apply(temp, source, sourceRectangle); - - // Apply threshold binarization filter. - new BinaryThresholdProcessor(.5f).Apply(temp, sourceRectangle); - - // Search for the first white pixels - Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); - - // Reset the target pixel to the correct size. - target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); - this.cropRectangle = rectangle; - } - - /// - protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - // Copy the pixels over. - if (source.Bounds == target.Bounds) - { - target.ClonePixels(target.Width, target.Height, source.Pixels); - } - } - } -} \ No newline at end of file