From 207c1fa4e773006d30d19dad3b0f186c59442d52 Mon Sep 17 00:00:00 2001 From: James South Date: Fri, 19 Sep 2014 00:09:33 +0100 Subject: [PATCH] Adding pixelate processor Former-commit-id: 89965b4a0b6f41159b90655139045dd2bcfcea44 --- src/ImageProcessor/ImageFactory.cs | 22 ++++ src/ImageProcessor/ImageProcessor.csproj | 1 + src/ImageProcessor/Processors/Pixelate.cs | 134 ++++++++++++++++++++++ src/ImageProcessorConsole/Program.cs | 9 +- 4 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 src/ImageProcessor/Processors/Pixelate.cs diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs index 1398b8c9f..b27686231 100644 --- a/src/ImageProcessor/ImageFactory.cs +++ b/src/ImageProcessor/ImageFactory.cs @@ -650,6 +650,28 @@ namespace ImageProcessor return this; } + /// + /// Pixelates an image with the given size. + /// + /// + /// The size of the pixels to create. + /// + /// The area in which to pixelate the image. If not set, the whole image is pixelated. + /// + /// + /// The current instance of the class. + /// + public ImageFactory Pixelate(int pixelSize, Rectangle? rectangle = null) + { + if (this.ShouldProcess && pixelSize > 0) + { + Pixelate pixelate = new Pixelate { DynamicParameter = new Tuple(pixelSize, rectangle) }; + this.CurrentImageFormat.ApplyProcessor(pixelate.ProcessImage, this); + } + + return this; + } + /// /// Alters the output quality of the current image. /// diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj index 1243ce923..a3835a061 100644 --- a/src/ImageProcessor/ImageProcessor.csproj +++ b/src/ImageProcessor/ImageProcessor.csproj @@ -125,6 +125,7 @@ + diff --git a/src/ImageProcessor/Processors/Pixelate.cs b/src/ImageProcessor/Processors/Pixelate.cs new file mode 100644 index 000000000..ebec47f43 --- /dev/null +++ b/src/ImageProcessor/Processors/Pixelate.cs @@ -0,0 +1,134 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// Copyright (c) James South. +// Licensed under the Apache License, Version 2.0. +// +// +// Encapsulates methods to pixelate an image. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace ImageProcessor.Processors +{ + using System; + using System.Collections.Generic; + using System.Drawing; + + using ImageProcessor.Common.Exceptions; + using ImageProcessor.Imaging; + + /// + /// Encapsulates methods to pixelate an image. + /// + public class Pixelate : IGraphicsProcessor + { + /// + /// Initializes a new instance of the class. + /// + public Pixelate() + { + this.Settings = new Dictionary(); + } + + /// + /// Gets or sets the dynamic parameter. + /// + public dynamic DynamicParameter + { + get; + set; + } + + /// + /// Gets or sets any additional settings required by the processor. + /// + public Dictionary Settings + { + get; + set; + } + + /// + /// Processes the image. + /// + /// + /// The current instance of the class containing + /// the image to process. + /// + /// + /// The processed image from the current instance of the class. + /// + public Image ProcessImage(ImageFactory factory) + { + Bitmap newImage = null; + Image image = factory.Image; + + try + { + Tuple parameters = this.DynamicParameter; + int size = parameters.Item1; + Rectangle rectangle = parameters.Item2.HasValue + ? parameters.Item2.Value + : new Rectangle(0, 0, image.Width, image.Height); + int x = rectangle.X; + int y = rectangle.Y; + int offset = size / 2; + int width = rectangle.Width; + int height = rectangle.Height; + int maxWidth = image.Width; + int maxHeight = image.Height; + + newImage = new Bitmap(image); + + 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) + { + int offsetX = offset; + int offsetY = offset; + + // Make sure that the offset is within the boundary of the image. + while (i + offsetX >= maxWidth) + { + offsetX--; + } + + while (j + offsetY >= maxHeight) + { + offsetY--; + } + + // 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++) + { + fastBitmap.SetPixel(k, l, pixel); + } + } + } + } + } + + image.Dispose(); + image = newImage; + } + catch (Exception ex) + { + if (newImage != null) + { + newImage.Dispose(); + } + + throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); + } + + return image; + } + } +} diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs index 5b605dfca..89a510e25 100644 --- a/src/ImageProcessorConsole/Program.cs +++ b/src/ImageProcessorConsole/Program.cs @@ -18,6 +18,7 @@ namespace ImageProcessorConsole using System.Linq; using ImageProcessor; using ImageProcessor.Imaging; + using ImageProcessor.Imaging.Filters; using ImageProcessor.Plugins.Cair; using ImageProcessor.Plugins.Cair.Imaging; @@ -60,7 +61,7 @@ namespace ImageProcessorConsole { using (ImageFactory imageFactory = new ImageFactory(true)) { - Size size = new Size(448, 0); + Size size = new Size(800, 0); //ContentAwareResizeLayer layer = new ContentAwareResizeLayer(size) //{ @@ -72,9 +73,9 @@ namespace ImageProcessorConsole //.BackgroundColor(Color.White) //.Resize(new Size((int)(size.Width * 1.1), 0)) //.ContentAwareResize(layer) - .Constrain(size) - .Hue(180) - .Quality(100) + //.Constrain(size) + //.Filter(MatrixFilters.HiSatch) + .Pixelate(8) .Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name))); stopwatch.Stop();