From 22d661d16854044360299be6d5217f4fd536005d Mon Sep 17 00:00:00 2001 From: James South Date: Mon, 22 Sep 2014 14:20:19 +0100 Subject: [PATCH] Adding replace color functionality Former-commit-id: 47ef8ddfa95092974213c3312125f5b171f7a2f3 --- src/ImageProcessor/ImageFactory.cs | 37 ++++++++++++- src/ImageProcessor/ImageProcessor.csproj | 1 + src/ImageProcessor/Processors/ReplaceColor.cs | 55 +++++++++++++++++-- src/ImageProcessorConsole/Program.cs | 3 +- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index 510803eb5..3de01f167 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -660,7 +660,7 @@ namespace ImageProcessor /// public ImageFactory Quality(int percentage) { - if (this.ShouldProcess) + if (percentage <= 100 && percentage >= 0 && this.ShouldProcess) { this.CurrentImageFormat.Quality = percentage; } @@ -668,6 +668,41 @@ namespace ImageProcessor return this; } + /// + /// Replaces a color within the current image. + /// + /// + /// The target . + /// + /// + /// The replacement . + /// + /// + /// A value between 0 and 100 with which to alter the target detection accuracy. + /// + /// + /// The . + /// + public ImageFactory ReplaceColor(Color target, Color replacement, int fuzziness = 0) + { + // Sanitize the input. + if (fuzziness < 0 || fuzziness > 100) + { + fuzziness = 0; + } + + if (this.ShouldProcess && target != Color.Empty && replacement != Color.Empty) + { + ReplaceColor replaceColor = new ReplaceColor + { + DynamicParameter = new Tuple(target, replacement, fuzziness) + }; + this.CurrentImageFormat.ApplyProcessor(replaceColor.ProcessImage, this); + } + + return this; + } + /// /// Resizes the current image to the given dimensions. /// diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj index 0ffb91bf5..4a44398ab 100644 --- a/src/ImageProcessor/ImageProcessor.csproj +++ b/src/ImageProcessor/ImageProcessor.csproj @@ -128,6 +128,7 @@ + diff --git a/src/ImageProcessor/Processors/ReplaceColor.cs b/src/ImageProcessor/Processors/ReplaceColor.cs index 37b59b935..a8a7f810e 100644 --- a/src/ImageProcessor/Processors/ReplaceColor.cs +++ b/src/ImageProcessor/Processors/ReplaceColor.cs @@ -1,14 +1,24 @@ -namespace ImageProcessor.Processors +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// Encapsulates methods allowing the replacement of a color within an image. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Processors { using System; using System.Collections.Generic; using System.Drawing; using ImageProcessor.Common.Exceptions; + using ImageProcessor.Common.Extensions; using ImageProcessor.Imaging; /// /// Encapsulates methods allowing the replacement of a color within an image. - /// /// public class ReplaceColor : IGraphicsProcessor { @@ -57,20 +67,55 @@ { Tuple parameters = this.DynamicParameter; Color original = parameters.Item1; + byte originalR = original.R; + byte originalG = original.G; + byte originalB = original.B; + Color replacement = parameters.Item2; - int threshold = parameters.Item3; + byte replacementR = original.R; + byte replacementG = replacement.G; + byte replacementB = replacement.B; + + int fuzziness = parameters.Item3; newImage = new Bitmap(image); + int width = image.Width; + int height = image.Height; using (FastBitmap fastBitmap = new FastBitmap(newImage)) { - + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + // Get the pixel color. + Color currentColor = fastBitmap.GetPixel(x, y); + byte currentR = currentColor.R; + byte currentG = currentColor.B; + byte currentB = currentColor.B; + // Test whether it is in the expected range. + if (currentR <= originalR + fuzziness && currentR >= originalR - fuzziness) + { + if (currentG <= originalG + fuzziness && currentG >= originalG - fuzziness) + { + if (currentB <= originalB + fuzziness && currentB >= originalB - fuzziness) + { + // Ensure the values are withing an acceptable byte range + // and set the new value. + byte r = (originalR - currentR + replacementR).ToByte(); + byte g = (originalG - currentG + replacementG).ToByte(); + byte b = (originalB - currentB + replacementB).ToByte(); + fastBitmap.SetPixel(x, y, Color.FromArgb(currentColor.A, r, g, b)); + } + } + } + } + } } image.Dispose(); image = newImage; - } catch (Exception ex) { diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs index 73bc58733..b0e7cb654 100644 --- a/src/ImageProcessorConsole/Program.cs +++ b/src/ImageProcessorConsole/Program.cs @@ -74,7 +74,8 @@ namespace ImageProcessorConsole //.Resize(new Size((int)(size.Width * 1.1), 0)) //.ContentAwareResize(layer) .Constrain(size) - .Filter(MatrixFilters.Comic) + .ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80) + //.Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.HiSatch) //.Pixelate(8) //.GaussianSharpen(10)