From bf621fb317c1840ec3548a4cbe6518211c36cdf0 Mon Sep 17 00:00:00 2001 From: James South Date: Tue, 30 Sep 2014 00:40:02 +0100 Subject: [PATCH] Refactoring + Convolution filter update Former-commit-id: db48e9ad325b90b5b2648aaaa05636de05d7e9fb --- .../App.config | 0 .../ImageProcessor.Playground.csproj | 0 .../Program.cs | 4 +- .../Properties/AssemblyInfo.cs | 0 .../images/input/120430.gif.REMOVED.git-id | 0 .../images/input/1aaa.jpg.REMOVED.git-id | 0 .../input/2006-citybus.jpg.REMOVED.git-id | 0 .../images/input/2008.jpg.REMOVED.git-id | 0 .../input/2012-citybus.jpg.REMOVED.git-id | 0 .../images/input/4.sm.webp | 0 .../Arc-de-Triomphe-France.jpg.REMOVED.git-id | 0 .../images/input/Bikesgray.png.REMOVED.git-id | 0 .../images/input/IC580196.jpg.REMOVED.git-id | 0 .../images/input/Tl4Yb.gif.REMOVED.git-id | 0 .../images/input/Turtle.jpg | 0 .../Valve_original_(1).PNG.REMOVED.git-id | 0 ...e_triomphe_paris_france.jpg.REMOVED.git-id | 0 .../images/input/circle.png | 0 .../images/input/circle2.png | 0 .../images/input/crop-base-300x200.jpg | 3 + .../input/monster-whitebg.png2.REMOVED.git-id | 0 .../images/input/monster.png.REMOVED.git-id | 0 .../images/input/mountain.jpg.REMOVED.git-id | 0 .../images/input/nLpfllv.gif.REMOVED.git-id | 0 .../images/input/new-york.jpg.REMOVED.git-id | 0 .../input/night-bridge.png.REMOVED.git-id | 0 .../images/input/pixel.png3 | Bin .../images/input/rotate.jpg.REMOVED.git-id | 0 .../images/input/sample1.jpg | 0 ...Arc_de_triomphe-square1.jpg.REMOVED.git-id | 0 .../images/input/test.jpg.REMOVED.git-id | 0 .../images/input/test.webp | 0 .../input/tower - Copy.jpg2.REMOVED.git-id | 0 .../images/input/tower.jpg.REMOVED.git-id | 0 src/ImageProcessor.sln | 2 +- src/ImageProcessor/ImageFactory.cs | 11 +- src/ImageProcessor/ImageProcessor.csproj | 9 +- .../Filters/Artistic/OilPaintingFilter.cs | 183 ++++++++++++++++++ .../Filters/Binarization/BinaryThreshold.cs | 5 +- .../EdgeDetection/ConvolutionFilter.cs | 134 ++++++++++++- .../Filters/EdgeDetection/I2DEdgeFilter.cs | 23 +++ .../Filters/EdgeDetection/IEdgeFilter.cs | 5 - .../EdgeDetection/KayyaliEdgeFilter.cs | 2 +- .../Filters/EdgeDetection/KirschEdgeFilter.cs | 2 +- .../EdgeDetection/Laplacian3x3Filter.cs | 36 ++++ .../EdgeDetection/Laplacian5X5Filter.cs | 38 ++++ .../LaplacianOfGaussianFilter.cs | 38 ++++ .../EdgeDetection/PrewittEdgeFilter.cs | 2 +- .../EdgeDetection/RobertsCrossEdgeFilter.cs | 2 +- .../Filters/EdgeDetection/ScharrEdgeFilter.cs | 2 +- .../Filters/EdgeDetection/SobelEdgeFilter.cs | 2 +- .../Filters/Photo/ComicMatrixFilter.cs | 149 +------------- .../Imaging/Formats/FormatUtilities.cs | 1 + .../Imaging/{ => MetaData}/ExifPropertyTag.cs | 2 +- .../{ => MetaData}/ExifPropertyTagType.cs | 2 +- src/ImageProcessor/Processors/AutoRotate.cs | 2 +- src/ImageProcessor/Processors/DetectEdges.cs | 28 +-- src/ImageProcessor/Processors/EntropyCrop.cs | 4 +- src/ImageProcessor/Processors/Hue.cs | 16 +- src/ImageProcessor/Processors/Pixelate.cs | 16 +- src/ImageProcessor/Processors/ReplaceColor.cs | 6 +- src/ImageProcessor/Settings.StyleCop | 1 + src/ImageProcessor_Mono.sln | 2 +- 63 files changed, 534 insertions(+), 198 deletions(-) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/App.config (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/ImageProcessor.Playground.csproj (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/Program.cs (95%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/Properties/AssemblyInfo.cs (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/120430.gif.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/1aaa.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/2006-citybus.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/2008.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/2012-citybus.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/4.sm.webp (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/Arc-de-Triomphe-France.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/Bikesgray.png.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/IC580196.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/Tl4Yb.gif.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/Turtle.jpg (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/Valve_original_(1).PNG.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/arc_de_triomphe_paris_france.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/circle.png (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/circle2.png (100%) create mode 100644 src/ImageProcessor.Playground/images/input/crop-base-300x200.jpg rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/monster-whitebg.png2.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/monster.png.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/mountain.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/nLpfllv.gif.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/new-york.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/night-bridge.png.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/pixel.png3 (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/rotate.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/sample1.jpg (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/test.jpg.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/test.webp (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/tower - Copy.jpg2.REMOVED.git-id (100%) rename src/{ImageProcessorConsole => ImageProcessor.Playground}/images/input/tower.jpg.REMOVED.git-id (100%) create mode 100644 src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs create mode 100644 src/ImageProcessor/Imaging/Filters/EdgeDetection/I2DEdgeFilter.cs create mode 100644 src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian3x3Filter.cs create mode 100644 src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian5X5Filter.cs create mode 100644 src/ImageProcessor/Imaging/Filters/EdgeDetection/LaplacianOfGaussianFilter.cs rename src/ImageProcessor/Imaging/{ => MetaData}/ExifPropertyTag.cs (99%) rename src/ImageProcessor/Imaging/{ => MetaData}/ExifPropertyTagType.cs (98%) diff --git a/src/ImageProcessorConsole/App.config b/src/ImageProcessor.Playground/App.config similarity index 100% rename from src/ImageProcessorConsole/App.config rename to src/ImageProcessor.Playground/App.config diff --git a/src/ImageProcessorConsole/ImageProcessor.Playground.csproj b/src/ImageProcessor.Playground/ImageProcessor.Playground.csproj similarity index 100% rename from src/ImageProcessorConsole/ImageProcessor.Playground.csproj rename to src/ImageProcessor.Playground/ImageProcessor.Playground.csproj diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessor.Playground/Program.cs similarity index 95% rename from src/ImageProcessorConsole/Program.cs rename to src/ImageProcessor.Playground/Program.cs index 2d15f83d47..16532da978 100644 --- a/src/ImageProcessorConsole/Program.cs +++ b/src/ImageProcessor.Playground/Program.cs @@ -19,6 +19,7 @@ namespace ImageProcessor.PlayGround using ImageProcessor; using ImageProcessor.Imaging; + using ImageProcessor.Imaging.Filters.EdgeDetection; using ImageProcessor.Imaging.Filters.Photo; /// @@ -76,8 +77,9 @@ namespace ImageProcessor.PlayGround //.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80) //.Resize(layer) //.DetectEdges(new KirschEdgeFilter()) + //.DetectEdges(new LaplacianOfGaussianFilter()) //.EntropyCrop() - .Filter(MatrixFilters.Polaroid) + .Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.HiSatch) //.Pixelate(8) diff --git a/src/ImageProcessorConsole/Properties/AssemblyInfo.cs b/src/ImageProcessor.Playground/Properties/AssemblyInfo.cs similarity index 100% rename from src/ImageProcessorConsole/Properties/AssemblyInfo.cs rename to src/ImageProcessor.Playground/Properties/AssemblyInfo.cs diff --git a/src/ImageProcessorConsole/images/input/120430.gif.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/120430.gif.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/120430.gif.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/120430.gif.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/1aaa.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/1aaa.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/1aaa.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/1aaa.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/2006-citybus.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/2006-citybus.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/2006-citybus.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/2006-citybus.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/2008.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/2008.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/2008.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/2008.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/2012-citybus.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/2012-citybus.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/2012-citybus.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/2012-citybus.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/4.sm.webp b/src/ImageProcessor.Playground/images/input/4.sm.webp similarity index 100% rename from src/ImageProcessorConsole/images/input/4.sm.webp rename to src/ImageProcessor.Playground/images/input/4.sm.webp diff --git a/src/ImageProcessorConsole/images/input/Arc-de-Triomphe-France.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/Arc-de-Triomphe-France.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/Arc-de-Triomphe-France.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/Arc-de-Triomphe-France.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/Bikesgray.png.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/Bikesgray.png.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/Bikesgray.png.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/Bikesgray.png.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/IC580196.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/IC580196.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/IC580196.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/IC580196.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/Tl4Yb.gif.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/Tl4Yb.gif.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/Tl4Yb.gif.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/Tl4Yb.gif.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/Turtle.jpg b/src/ImageProcessor.Playground/images/input/Turtle.jpg similarity index 100% rename from src/ImageProcessorConsole/images/input/Turtle.jpg rename to src/ImageProcessor.Playground/images/input/Turtle.jpg diff --git a/src/ImageProcessorConsole/images/input/Valve_original_(1).PNG.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/Valve_original_(1).PNG.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/Valve_original_(1).PNG.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/Valve_original_(1).PNG.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/arc_de_triomphe_paris_france.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/arc_de_triomphe_paris_france.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/arc_de_triomphe_paris_france.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/arc_de_triomphe_paris_france.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/circle.png b/src/ImageProcessor.Playground/images/input/circle.png similarity index 100% rename from src/ImageProcessorConsole/images/input/circle.png rename to src/ImageProcessor.Playground/images/input/circle.png diff --git a/src/ImageProcessorConsole/images/input/circle2.png b/src/ImageProcessor.Playground/images/input/circle2.png similarity index 100% rename from src/ImageProcessorConsole/images/input/circle2.png rename to src/ImageProcessor.Playground/images/input/circle2.png diff --git a/src/ImageProcessor.Playground/images/input/crop-base-300x200.jpg b/src/ImageProcessor.Playground/images/input/crop-base-300x200.jpg new file mode 100644 index 0000000000..ec59d2d314 --- /dev/null +++ b/src/ImageProcessor.Playground/images/input/crop-base-300x200.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:494265979d208de49893f3e257b8aeaed13a864d462013a62446fdc30503ef36 +size 14136 diff --git a/src/ImageProcessorConsole/images/input/monster-whitebg.png2.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/monster-whitebg.png2.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/monster-whitebg.png2.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/monster-whitebg.png2.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/monster.png.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/monster.png.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/monster.png.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/monster.png.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/mountain.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/mountain.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/mountain.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/mountain.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/nLpfllv.gif.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/nLpfllv.gif.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/nLpfllv.gif.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/nLpfllv.gif.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/new-york.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/new-york.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/new-york.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/new-york.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/night-bridge.png.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/night-bridge.png.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/night-bridge.png.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/night-bridge.png.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/pixel.png3 b/src/ImageProcessor.Playground/images/input/pixel.png3 similarity index 100% rename from src/ImageProcessorConsole/images/input/pixel.png3 rename to src/ImageProcessor.Playground/images/input/pixel.png3 diff --git a/src/ImageProcessorConsole/images/input/rotate.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/rotate.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/rotate.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/rotate.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/sample1.jpg b/src/ImageProcessor.Playground/images/input/sample1.jpg similarity index 100% rename from src/ImageProcessorConsole/images/input/sample1.jpg rename to src/ImageProcessor.Playground/images/input/sample1.jpg diff --git a/src/ImageProcessorConsole/images/input/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/test.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/test.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/test.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/test.jpg.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/test.webp b/src/ImageProcessor.Playground/images/input/test.webp similarity index 100% rename from src/ImageProcessorConsole/images/input/test.webp rename to src/ImageProcessor.Playground/images/input/test.webp diff --git a/src/ImageProcessorConsole/images/input/tower - Copy.jpg2.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/tower - Copy.jpg2.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/tower - Copy.jpg2.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/tower - Copy.jpg2.REMOVED.git-id diff --git a/src/ImageProcessorConsole/images/input/tower.jpg.REMOVED.git-id b/src/ImageProcessor.Playground/images/input/tower.jpg.REMOVED.git-id similarity index 100% rename from src/ImageProcessorConsole/images/input/tower.jpg.REMOVED.git-id rename to src/ImageProcessor.Playground/images/input/tower.jpg.REMOVED.git-id diff --git a/src/ImageProcessor.sln b/src/ImageProcessor.sln index 52fa46752d..335de55aa3 100644 --- a/src/ImageProcessor.sln +++ b/src/ImageProcessor.sln @@ -22,7 +22,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web", "Image EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Plugins.WebP", "Plugins\ImageProcessor\ImageProcessor.Plugins.WebP\ImageProcessor.Plugins.WebP.csproj", "{2CF69699-959A-44DC-A281-4E2596C25043}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Playground", "ImageProcessorConsole\ImageProcessor.Playground.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Playground", "ImageProcessor.Playground\ImageProcessor.Playground.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web.UnitTests", "ImageProcessor.Web.UnitTests\ImageProcessor.Web.UnitTests.csproj", "{961340C8-8C93-401D-A0A2-FF9EC61E5260}" EndProject diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index 08fb876b46..060524c863 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -288,11 +288,20 @@ namespace ImageProcessor return this; } + /// + /// Crops an image to the area of greatest entropy. + /// + /// + /// The threshold in bytes to control the entropy. + /// + /// + /// The current instance of the class. + /// public ImageFactory EntropyCrop(byte threshold = 128) { if (this.ShouldProcess) { - EntropyCrop autoCrop = new EntropyCrop() { DynamicParameter = threshold }; + EntropyCrop autoCrop = new EntropyCrop { DynamicParameter = threshold }; this.CurrentImageFormat.ApplyProcessor(autoCrop.ProcessImage, this); } diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj index ee7f452678..dd4fa80151 100644 --- a/src/ImageProcessor/ImageProcessor.csproj +++ b/src/ImageProcessor/ImageProcessor.csproj @@ -76,9 +76,14 @@ + + + + + @@ -92,11 +97,11 @@ - + - + diff --git a/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs b/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs new file mode 100644 index 0000000000..d659f62038 --- /dev/null +++ b/src/ImageProcessor/Imaging/Filters/Artistic/OilPaintingFilter.cs @@ -0,0 +1,183 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// The oil painting filter. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Imaging.Filters.Artistic +{ + using System; + using System.Drawing; + + using ImageProcessor.Common.Extensions; + + /// + /// The oil painting filter. + /// + public class OilPaintingFilter + { + /// + /// The levels. + /// + private int levels; + + /// + /// The brush size. + /// + private int brushSize; + + /// + /// Initializes a new instance of the class. + /// + /// + /// The number of levels. + /// + /// + /// The brush size. + /// + public OilPaintingFilter(int levels, int brushSize) + { + this.levels = levels; + this.brushSize = brushSize; + } + + /// + /// Gets or sets the number of levels. + /// + public int Levels + { + get + { + return this.levels; + } + + set + { + if (value > 0) + { + this.levels = value; + } + } + } + + /// + /// Gets or sets the brush size. + /// + public int BrushSize + { + get + { + return this.brushSize; + } + + set + { + if (value > 0) + { + this.brushSize = value; + } + } + } + + /// + /// Applies the filter. TODO: Make this class implement an interface? + /// + /// + /// The source. + /// + /// + /// The . + /// + public Bitmap ApplyFilter(Bitmap source) + { + int width = source.Width; + int height = source.Height; + + int radius = this.brushSize >> 1; + + Bitmap destination = new Bitmap(width, height); + using (FastBitmap sourceBitmap = new FastBitmap(source)) + { + using (FastBitmap destinationBitmap = new FastBitmap(destination)) + { + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int maxIntensity = 0; + int maxIndex = 0; + int[] intensityBin = new int[this.levels]; + int[] blueBin = new int[this.levels]; + int[] greenBin = new int[this.levels]; + int[] redBin = new int[this.levels]; + + for (int i = 0; i <= radius; i++) + { + int ir = i - radius; + int offsetY = y + ir; + + // Skip the current row + if (offsetY < 0) + { + continue; + } + + // Outwith the current bounds so break. + if (offsetY >= height) + { + break; + } + + for (int fx = 0; fx <= radius; fx++) + { + int jr = fx - radius; + int offsetX = x + jr; + + // Skip the column + if (offsetX < 0) + { + continue; + } + + if (offsetX < width) + { + Color color = sourceBitmap.GetPixel(offsetX, offsetY); + + byte sourceBlue = color.B; + byte sourceGreen = color.G; + byte sourceRed = color.R; + + int currentIntensity = (int)Math.Round(((sourceBlue + sourceGreen + sourceRed) / 3.0 * (this.levels - 1)) / 255.0); + + intensityBin[currentIntensity] += 1; + blueBin[currentIntensity] += sourceBlue; + greenBin[currentIntensity] += sourceGreen; + redBin[currentIntensity] += sourceRed; + + if (intensityBin[currentIntensity] > maxIntensity) + { + maxIntensity = intensityBin[currentIntensity]; + maxIndex = currentIntensity; + } + } + } + } + + byte blue = Math.Abs(blueBin[maxIndex] / maxIntensity).ToByte(); + byte green = Math.Abs(greenBin[maxIndex] / maxIntensity).ToByte(); + byte red = Math.Abs(redBin[maxIndex] / maxIntensity).ToByte(); + + destinationBitmap.SetPixel(x, y, Color.FromArgb(red, green, blue)); + } + } + } + } + + return destination; + } + } +} diff --git a/src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs b/src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs index b420a65881..96478497f2 100644 --- a/src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs +++ b/src/ImageProcessor/Imaging/Filters/Binarization/BinaryThreshold.cs @@ -61,10 +61,9 @@ namespace ImageProcessor.Imaging.Filters.Binarization using (FastBitmap sourceBitmap = new FastBitmap(source)) { - - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { Color color = sourceBitmap.GetPixel(x, y); sourceBitmap.SetPixel(x, y, color.B >= this.threshold ? Color.White : Color.Black); diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs index 9d6681ffcf..98a4e4c0e2 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ConvolutionFilter.cs @@ -83,7 +83,137 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection try { double[,] horizontalFilter = this.edgeFilter.HorizontalGradientOperator; - double[,] verticalFilter = this.edgeFilter.VerticalGradientOperator; + + int kernelLength = horizontalFilter.GetLength(0); + int radius = kernelLength >> 1; + + using (FastBitmap sourceBitmap = new FastBitmap(input)) + { + using (FastBitmap destinationBitmap = new FastBitmap(destination)) + { + // Loop through the pixels. + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + double rX = 0; + double gX = 0; + double 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; + + // Skip the current row + if (offsetY < 0) + { + continue; + } + + // Outwith the current bounds so break. + if (offsetY >= height) + { + break; + } + + for (int fx = 0; fx < kernelLength; fx++) + { + int fxr = fx - radius; + int offsetX = x + fxr; + + // Skip the column + if (offsetX < 0) + { + continue; + } + + if (offsetX < width) + { + Color currentColor = sourceBitmap.GetPixel(offsetX, offsetY); + double r = currentColor.R; + double g = currentColor.G; + double b = currentColor.B; + + rX += horizontalFilter[fy, fx] * r; + + gX += horizontalFilter[fy, fx] * g; + + bX += horizontalFilter[fy, fx] * b; + } + } + } + + // Apply the equation and sanitize. + byte red = rX.ToByte(); + byte green = gX.ToByte(); + byte blue = bX.ToByte(); + + Color newColor = Color.FromArgb(red, green, blue); + destinationBitmap.SetPixel(x, y, newColor); + } + } + } + } + } + finally + { + // We created a new image. Cleanup. + input.Dispose(); + } + + // Draw a black rectangle around the area to ensure that the first row/column in covered. + using (Graphics graphics = Graphics.FromImage(destination)) + { + // Draw an edge around the image. + using (Pen blackPen = new Pen(Color.Black)) + { + blackPen.Width = 4; + graphics.DrawRectangle(blackPen, new Rectangle(0, 0, destination.Width, destination.Height)); + } + } + + return destination; + } + + /// + /// Processes the given bitmap to apply the current instances . + /// + /// The image to process. + /// A processed bitmap. + public Bitmap Process2DFilter(Bitmap source) + { + int width = source.Width; + int height = source.Height; + + Bitmap destination = new Bitmap(width, height, PixelFormat.Format32bppArgb); + Bitmap input = new Bitmap(width, height, PixelFormat.Format32bppArgb); + + using (Graphics graphics = Graphics.FromImage(input)) + { + Rectangle rectangle = new Rectangle(0, 0, width, height); + if (this.greyscale) + { + // If it's greyscale apply a colormatrix to the image. + using (ImageAttributes attributes = new ImageAttributes()) + { + attributes.SetColorMatrix(ColorMatrixes.GreyScale); + graphics.DrawImage(source, rectangle, 0, 0, width, height, GraphicsUnit.Pixel, attributes); + } + } + else + { + // Fixes an issue with transparency not converting properly. + graphics.Clear(Color.Transparent); + graphics.DrawImage(source, rectangle); + } + } + + try + { + double[,] horizontalFilter = this.edgeFilter.HorizontalGradientOperator; + double[,] verticalFilter = ((I2DEdgeFilter)this.edgeFilter).VerticalGradientOperator; int kernelLength = horizontalFilter.GetLength(0); int radius = kernelLength >> 1; @@ -176,7 +306,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection // Draw an edge around the image. using (Pen blackPen = new Pen(Color.Black)) { - blackPen.Width = 1; + blackPen.Width = 4; graphics.DrawRectangle(blackPen, new Rectangle(0, 0, destination.Width, destination.Height)); } } diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/I2DEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/I2DEdgeFilter.cs new file mode 100644 index 0000000000..e6568c19f1 --- /dev/null +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/I2DEdgeFilter.cs @@ -0,0 +1,23 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// Describes properties for creating 2 dimension edge detection filters. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Imaging.Filters.EdgeDetection +{ + /// + /// Describes properties for creating 2 dimension edge detection filters. + /// + public interface I2DEdgeFilter : IEdgeFilter + { + /// + /// Gets the vertical gradient operator. + /// + double[,] VerticalGradientOperator { get; } + } +} diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs index 18a3bc8cc4..b89ce902dc 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/IEdgeFilter.cs @@ -19,10 +19,5 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// Gets the horizontal gradient operator. /// double[,] HorizontalGradientOperator { get; } - - /// - /// Gets the vertical gradient operator. - /// - double[,] VerticalGradientOperator { get; } } } diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs index f597b9f5eb..001d405110 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/KayyaliEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Kayyali operator filter. /// /// - public class KayyaliEdgeFilter : IEdgeFilter + public class KayyaliEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs index 9069870d8d..47987078ed 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/KirschEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Kirsch operator filter. /// /// - public class KirschEdgeFilter : IEdgeFilter + public class KirschEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian3x3Filter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian3x3Filter.cs new file mode 100644 index 0000000000..e4c6944961 --- /dev/null +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian3x3Filter.cs @@ -0,0 +1,36 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// The Laplacian 3 x 3 operator filter. +// +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Imaging.Filters.EdgeDetection +{ + /// + /// The Laplacian 3 x 3 operator filter. + /// + /// + public class Laplacian3X3Filter : IEdgeFilter + { + /// + /// Gets the horizontal gradient operator. + /// + public double[,] HorizontalGradientOperator + { + get + { + return new double[,] + { + { -1, -1, -1 }, + { -1, 8, -1 }, + { -1, -1, -1 } + }; + } + } + } +} diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian5X5Filter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian5X5Filter.cs new file mode 100644 index 0000000000..97bd90cf83 --- /dev/null +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/Laplacian5X5Filter.cs @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// The Laplacian 5 x 5 operator filter. +// +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Imaging.Filters.EdgeDetection +{ + /// + /// The Laplacian 5 x 5 operator filter. + /// + /// + public class Laplacian5X5Filter : IEdgeFilter + { + /// + /// Gets the horizontal gradient operator. + /// + public double[,] HorizontalGradientOperator + { + get + { + return new double[,] + { + { -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1 }, + { -1, -1, 24, -1, -1 }, + { -1, -1, -1, -1, -1 }, + { -1, -1, -1, -1, -1 } + }; + } + } + } +} diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/LaplacianOfGaussianFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/LaplacianOfGaussianFilter.cs new file mode 100644 index 0000000000..b2c4cdd2d1 --- /dev/null +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/LaplacianOfGaussianFilter.cs @@ -0,0 +1,38 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// The Laplacian of Gaussian operator filter. +// +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Imaging.Filters.EdgeDetection +{ + /// + /// The Laplacian of Gaussian operator filter. + /// + /// + public class LaplacianOfGaussianFilter : IEdgeFilter + { + /// + /// Gets the horizontal gradient operator. + /// + public double[,] HorizontalGradientOperator + { + get + { + return new double[,] + { + { 0, 0, -1, 0, 0 }, + { 0, -1, -2, -1, 0 }, + { -1, -2, 16, -2, -1 }, + { 0, -1, -2, -1, 0 }, + { 0, 0, -1, 0, 0 } + }; + } + } + } +} diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs index d13f3ae404..91b3272dea 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/PrewittEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Prewitt operator filter. /// /// - public class PrewittEdgeFilter : IEdgeFilter + public class PrewittEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs index db75c03ab6..b121f9a453 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/RobertsCrossEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Roberts Cross operator filter. /// /// - public class RobertsCrossEdgeFilter : IEdgeFilter + public class RobertsCrossEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs index 2d5915d368..c346cb0834 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/ScharrEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Scharr operator filter. /// /// - public class ScharrEdgeFilter : IEdgeFilter + public class ScharrEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs b/src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs index bf116164d8..99fd1cf5e8 100644 --- a/src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/EdgeDetection/SobelEdgeFilter.cs @@ -15,7 +15,7 @@ namespace ImageProcessor.Imaging.Filters.EdgeDetection /// The Sobel operator filter. /// /// - public class SobelEdgeFilter : IEdgeFilter + public class SobelEdgeFilter : I2DEdgeFilter { /// /// Gets the horizontal gradient operator. diff --git a/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs index 6c63b49cb1..0f5bcad66f 100644 --- a/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs +++ b/src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs @@ -10,7 +10,6 @@ namespace ImageProcessor.Imaging.Filters.Photo { - #region Using using System; using System.Drawing; using System.Drawing.Drawing2D; @@ -18,8 +17,7 @@ namespace ImageProcessor.Imaging.Filters.Photo using System.Runtime.InteropServices; using ImageProcessor.Common.Extensions; - - #endregion + using ImageProcessor.Imaging.Filters.Artistic; /// /// Encapsulates methods with which to add a comic filter to an image. @@ -62,8 +60,8 @@ namespace ImageProcessor.Imaging.Filters.Photo highBitmap = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); // Apply a oil painting filter to the image. - highBitmap = OilPaintFilter((Bitmap)image, 3, 5); - + highBitmap = new OilPaintingFilter(3, 5).ApplyFilter((Bitmap)image); + // Draw the edges. edgeBitmap = DrawEdges((Bitmap)image, 120); @@ -109,7 +107,7 @@ namespace ImageProcessor.Imaging.Filters.Photo using (Graphics graphics = Graphics.FromImage(newImage)) { - // graphics.Clear(Color.Transparent); + graphics.Clear(Color.Transparent); // Overlay the image. graphics.DrawImage(highBitmap, 0, 0); @@ -166,135 +164,6 @@ namespace ImageProcessor.Imaging.Filters.Photo return image; } - /// - /// Applies an oil paint filter. - /// TODO: Move this to another class and add to the factory - /// - /// - /// The source bitmap. - /// - /// - /// The levels. - /// - /// - /// The filter size. - /// - /// - /// The . - /// - private static Bitmap OilPaintFilter(Bitmap sourceBitmap, int levels, int filterSize) - { - int width = sourceBitmap.Width; - int height = sourceBitmap.Height; - - BitmapData sourceData = sourceBitmap.LockBits( - new Rectangle(0, 0, width, height), - ImageLockMode.ReadOnly, - PixelFormat.Format32bppArgb); - - int strideWidth = sourceData.Stride; - int scanHeight = sourceData.Height; - - int bufferSize = strideWidth * scanHeight; - byte[] pixelBuffer = new byte[bufferSize]; - byte[] resultBuffer = new byte[bufferSize]; - - Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); - sourceBitmap.UnlockBits(sourceData); - - levels = levels - 1; - - int radius = filterSize >> 1; - - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - int maxIntensity = 0; - int maxIndex = 0; - int[] intensityBin = new int[levels + 1]; - int[] blueBin = new int[levels + 1]; - int[] greenBin = new int[levels + 1]; - int[] redBin = new int[levels + 1]; - - int byteOffset = (y * strideWidth) + (x * 4); - - for (int i = 0; i <= radius; i++) - { - int ir = i - radius; - int offsetY = y + ir; - - // Skip the current row - if (offsetY < 0) - { - continue; - } - - // Outwith the current bounds so break. - if (offsetY >= height) - { - break; - } - - for (int j = 0; j <= radius; j++) - { - int jr = j - radius; - int offsetX = x + jr; - - // Skip the column - if (offsetX < 0) - { - continue; - } - - if (offsetX < width) - { - int calcOffset = (offsetX * 4) + (offsetY * sourceData.Stride); - - byte sourceBlue = pixelBuffer[calcOffset]; - byte sourceGreen = pixelBuffer[calcOffset + 1]; - byte sourceRed = pixelBuffer[calcOffset + 2]; - - int currentIntensity = (int)Math.Round(((sourceBlue + sourceGreen + sourceRed) / 3.0 * levels) / 255.0); - - intensityBin[currentIntensity] += 1; - blueBin[currentIntensity] += sourceBlue; - greenBin[currentIntensity] += sourceGreen; - redBin[currentIntensity] += sourceRed; - - if (intensityBin[currentIntensity] > maxIntensity) - { - maxIntensity = intensityBin[currentIntensity]; - maxIndex = currentIntensity; - } - } - } - } - - double blue = Math.Abs(blueBin[maxIndex] / maxIntensity); - double green = Math.Abs(greenBin[maxIndex] / maxIntensity); - double red = Math.Abs(redBin[maxIndex] / maxIntensity); - - resultBuffer[byteOffset] = blue.ToByte(); - resultBuffer[byteOffset + 1] = green.ToByte(); - resultBuffer[byteOffset + 2] = red.ToByte(); - resultBuffer[byteOffset + 3] = pixelBuffer[byteOffset + 3]; - } - } - - Bitmap resultBitmap = new Bitmap(width, height); - - BitmapData resultData = resultBitmap.LockBits( - new Rectangle(0, 0, width, height), - ImageLockMode.WriteOnly, - PixelFormat.Format32bppArgb); - - Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); - resultBitmap.UnlockBits(resultData); - - return resultBitmap; - } - /// /// Detects and draws edges. /// TODO: Move this to another class and do edge detection. @@ -514,16 +383,16 @@ namespace ImageProcessor.Imaging.Filters.Photo int width = source.Width; int height = source.Height; - for (int i = 0; i < width; i++) + for (int y = 0; y < height; y++) { - for (int j = 0; j < height; j++) + for (int x = 0; x < width; x++) { - Color sourceColor = sourceBitmap.GetPixel(i, j); - Color destinationColor = destinationBitmap.GetPixel(i, j); + Color sourceColor = sourceBitmap.GetPixel(x, y); + Color destinationColor = destinationBitmap.GetPixel(x, y); if (destinationColor.A != 0) { - destinationBitmap.SetPixel(i, j, Color.FromArgb(sourceColor.B, destinationColor.R, destinationColor.G, destinationColor.B)); + destinationBitmap.SetPixel(x, y, Color.FromArgb(sourceColor.B, destinationColor.R, destinationColor.G, destinationColor.B)); } } } diff --git a/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs b/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs index 53025bf425..49378385db 100644 --- a/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs +++ b/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs @@ -19,6 +19,7 @@ namespace ImageProcessor.Imaging.Formats using System.Reflection; using ImageProcessor.Configuration; + using ImageProcessor.Imaging.MetaData; /// /// Utility methods for working with supported image formats. diff --git a/src/ImageProcessor/Imaging/ExifPropertyTag.cs b/src/ImageProcessor/Imaging/MetaData/ExifPropertyTag.cs similarity index 99% rename from src/ImageProcessor/Imaging/ExifPropertyTag.cs rename to src/ImageProcessor/Imaging/MetaData/ExifPropertyTag.cs index d3c26ff533..29bdd17456 100644 --- a/src/ImageProcessor/Imaging/ExifPropertyTag.cs +++ b/src/ImageProcessor/Imaging/MetaData/ExifPropertyTag.cs @@ -8,7 +8,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessor.Imaging +namespace ImageProcessor.Imaging.MetaData { /// /// The following enum gives descriptions of the property items supported by Windows GDI+. diff --git a/src/ImageProcessor/Imaging/ExifPropertyTagType.cs b/src/ImageProcessor/Imaging/MetaData/ExifPropertyTagType.cs similarity index 98% rename from src/ImageProcessor/Imaging/ExifPropertyTagType.cs rename to src/ImageProcessor/Imaging/MetaData/ExifPropertyTagType.cs index 1d0d470f70..02fa213627 100644 --- a/src/ImageProcessor/Imaging/ExifPropertyTagType.cs +++ b/src/ImageProcessor/Imaging/MetaData/ExifPropertyTagType.cs @@ -9,7 +9,7 @@ // // -------------------------------------------------------------------------------------------------------------------- -namespace ImageProcessor.Imaging +namespace ImageProcessor.Imaging.MetaData { /// /// Specifies the data type of the values stored in the value data member of that same PropertyItem object. diff --git a/src/ImageProcessor/Processors/AutoRotate.cs b/src/ImageProcessor/Processors/AutoRotate.cs index 7368d25744..67b91f81dc 100644 --- a/src/ImageProcessor/Processors/AutoRotate.cs +++ b/src/ImageProcessor/Processors/AutoRotate.cs @@ -16,7 +16,7 @@ namespace ImageProcessor.Processors using System.Drawing; using ImageProcessor.Common.Exceptions; - using ImageProcessor.Imaging; + using ImageProcessor.Imaging.MetaData; /// /// Performs auto-rotation to ensure that EXIF defined rotation is reflected in diff --git a/src/ImageProcessor/Processors/DetectEdges.cs b/src/ImageProcessor/Processors/DetectEdges.cs index db5c278366..1f0d480e8d 100644 --- a/src/ImageProcessor/Processors/DetectEdges.cs +++ b/src/ImageProcessor/Processors/DetectEdges.cs @@ -66,23 +66,27 @@ namespace ImageProcessor.Processors IEdgeFilter filter = parameters.Item1; bool greyscale = parameters.Item2; - //try - //{ + try + { ConvolutionFilter convolutionFilter = new ConvolutionFilter(filter, greyscale); - newImage = convolutionFilter.ProcessFilter((Bitmap)image); + + // Check and assign the correct method. Don't use reflection for speed. + newImage = filter is I2DEdgeFilter + ? convolutionFilter.Process2DFilter((Bitmap)image) + : convolutionFilter.ProcessFilter((Bitmap)image); image.Dispose(); image = newImage; - //} - //catch (Exception ex) - //{ - // if (newImage != null) - // { - // newImage.Dispose(); - // } + } + catch (Exception ex) + { + if (newImage != null) + { + newImage.Dispose(); + } - // throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); - //} + throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); + } return image; } diff --git a/src/ImageProcessor/Processors/EntropyCrop.cs b/src/ImageProcessor/Processors/EntropyCrop.cs index e92ccb64e7..f8e6a31991 100644 --- a/src/ImageProcessor/Processors/EntropyCrop.cs +++ b/src/ImageProcessor/Processors/EntropyCrop.cs @@ -18,7 +18,7 @@ namespace ImageProcessor.Processors using ImageProcessor.Imaging.Filters.EdgeDetection; /// - /// The auto crop. + /// Performs a crop on an image to the area of greatest entropy. /// public class EntropyCrop : IGraphicsProcessor { @@ -194,7 +194,7 @@ namespace ImageProcessor.Processors stopX = getMaxX(fastBitmap); } - return new Rectangle(startX, startY, stopX - startX + 1, stopY - startY + 1); + return new Rectangle(startX + 1, startY + 1, stopX - (startX + 1), stopY - (startY + 1)); } } } \ No newline at end of file diff --git a/src/ImageProcessor/Processors/Hue.cs b/src/ImageProcessor/Processors/Hue.cs index 11a7b48410..a3ccc4c5ef 100644 --- a/src/ImageProcessor/Processors/Hue.cs +++ b/src/ImageProcessor/Processors/Hue.cs @@ -69,25 +69,25 @@ namespace ImageProcessor.Processors { if (!rotate) { - for (int i = 0; i < width; i++) + for (int y = 0; y < height; y++) { - for (int j = 0; j < height; j++) + for (int x = 0; x < width; x++) { - HslaColor original = HslaColor.FromColor(fastBitmap.GetPixel(i, j)); + HslaColor original = HslaColor.FromColor(fastBitmap.GetPixel(x, y)); HslaColor altered = HslaColor.FromHslaColor(degrees / 360f, original.S, original.L, original.A); - fastBitmap.SetPixel(i, j, altered); + fastBitmap.SetPixel(x, y, altered); } } } else { - for (int i = 0; i < width; i++) + for (int y = 0; y < height; y++) { - for (int j = 0; j < height; j++) + for (int x = 0; x < width; x++) { - HslaColor original = HslaColor.FromColor(fastBitmap.GetPixel(i, j)); + HslaColor original = HslaColor.FromColor(fastBitmap.GetPixel(x, y)); HslaColor altered = HslaColor.FromHslaColor((original.H + (degrees / 360f)) % 1, original.S, original.L, original.A); - fastBitmap.SetPixel(i, j, altered); + fastBitmap.SetPixel(x, y, altered); } } } diff --git a/src/ImageProcessor/Processors/Pixelate.cs b/src/ImageProcessor/Processors/Pixelate.cs index ebec47f43b..437388eb0a 100644 --- a/src/ImageProcessor/Processors/Pixelate.cs +++ b/src/ImageProcessor/Processors/Pixelate.cs @@ -82,31 +82,31 @@ namespace ImageProcessor.Processors using (FastBitmap fastBitmap = new FastBitmap(newImage)) { - for (int i = x; i < x + width && i < maxWidth; i += size) + for (int j = y; j < y + height && j < maxHeight; j += size) { - for (int j = y; j < y + height && j < maxHeight; j += size) + for (int i = x; i < x + width && i < maxWidth; i += size) { int offsetX = offset; int offsetY = offset; // Make sure that the offset is within the boundary of the image. - while (i + offsetX >= maxWidth) + while (j + offsetY >= maxHeight) { - offsetX--; + offsetY--; } - while (j + offsetY >= maxHeight) + while (i + offsetX >= maxWidth) { - offsetY--; + offsetX--; } // Get the pixel color in the centre of the soon to be pixelated area. Color pixel = fastBitmap.GetPixel(i + offsetX, j + offsetY); // For each pixel in the pixelate size, set it to the centre color. - for (int k = i; k < i + size && k < maxWidth; k++) + for (int l = j; l < j + size && l < maxHeight; l++) { - for (int l = j; l < j + size && l < maxHeight; l++) + for (int k = i; k < i + size && k < maxWidth; k++) { fastBitmap.SetPixel(k, l, pixel); } diff --git a/src/ImageProcessor/Processors/ReplaceColor.cs b/src/ImageProcessor/Processors/ReplaceColor.cs index 9e3df1eeb9..81266be1e9 100644 --- a/src/ImageProcessor/Processors/ReplaceColor.cs +++ b/src/ImageProcessor/Processors/ReplaceColor.cs @@ -85,9 +85,9 @@ namespace ImageProcessor.Processors using (FastBitmap fastBitmap = new FastBitmap(newImage)) { - for (int x = 0; x < width; x++) + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) + for (int x = 0; x < width; x++) { // Get the pixel color. Color currentColor = fastBitmap.GetPixel(x, y); @@ -103,7 +103,7 @@ namespace ImageProcessor.Processors { if (currentB <= originalB + fuzziness && currentB >= originalB - fuzziness) { - // Ensure the values are withing an acceptable byte range + // Ensure the values are within an acceptable byte range // and set the new value. byte r = (originalR - currentR + replacementR).ToByte(); byte g = (originalG - currentG + replacementG).ToByte(); diff --git a/src/ImageProcessor/Settings.StyleCop b/src/ImageProcessor/Settings.StyleCop index 0a9f862fa5..b3c2af4287 100644 --- a/src/ImageProcessor/Settings.StyleCop +++ b/src/ImageProcessor/Settings.StyleCop @@ -7,6 +7,7 @@ dllimport gps Kayyali + Laplacian mmmm orig Scharr diff --git a/src/ImageProcessor_Mono.sln b/src/ImageProcessor_Mono.sln index 8b1e0fb375..85c0255608 100644 --- a/src/ImageProcessor_Mono.sln +++ b/src/ImageProcessor_Mono.sln @@ -16,7 +16,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web_NET4", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Web_NET45", "ImageProcessor.Web\NET45\ImageProcessor.Web_NET45.csproj", "{D011A778-59C8-4BFA-A770-C350216BF161}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessorConsole", "ImageProcessorConsole\ImageProcessorConsole.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.Playground", "ImageProcessor.Playground\ImageProcessor.Playground.csproj", "{7BF5274B-56A7-4B62-8105-E9BDF25BAFE7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageProcessor.UnitTests", "ImageProcessor.UnitTests\ImageProcessor.UnitTests.csproj", "{03CA9055-F997-428C-BF28-F50F991777C6}" EndProject