/// <summary> /// Processes the image. /// </summary> /// <param name="factory"> /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing /// the image to process. /// </param> /// <returns> /// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class. /// </returns> public Image ProcessImage(ImageFactory factory) { Bitmap newImage = null; Image image = factory.Image; Tuple<IEdgeFilter, bool> parameters = this.DynamicParameter; IEdgeFilter filter = parameters.Item1; bool greyscale = parameters.Item2; try { ConvolutionFilter convolutionFilter = new ConvolutionFilter(filter, greyscale); // 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(); } throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); } return image; }
/// <summary> /// Processes the image. /// </summary> /// <param name="factory"> /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing /// the image to process. /// </param> /// <returns> /// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class. /// </returns> public Image ProcessImage(ImageFactory factory) { Bitmap newImage = null; Bitmap grey = null; Image image = factory.Image; byte threshold = this.DynamicParameter; try { // Detect the edges then strip out middle shades. grey = new ConvolutionFilter(new SobelEdgeFilter(), true).Process2DFilter(image); grey = new BinaryThreshold(threshold).ProcessFilter(grey); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0); grey.Dispose(); newImage = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { graphics.DrawImage( image, new Rectangle(0, 0, rectangle.Width, rectangle.Height), rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, GraphicsUnit.Pixel); } // Reassign the image. image.Dispose(); image = newImage; if (factory.PreserveExifData && factory.ExifPropertyItems.Any()) { // Set the width EXIF data. factory.SetPropertyItem(ExifPropertyTag.ImageWidth, (ushort)image.Width); // Set the height EXIF data. factory.SetPropertyItem(ExifPropertyTag.ImageHeight, (ushort)image.Height); } } catch (Exception ex) { grey?.Dispose(); newImage?.Dispose(); throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); } return image; }
/// <summary> /// Processes the image. /// </summary> /// <param name="factory"> /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing /// the image to process. /// </param> /// <returns> /// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class. /// </returns> public Image ProcessImage(ImageFactory factory) { Bitmap newImage = null; Bitmap grey = null; Image image = factory.Image; byte threshold = this.DynamicParameter; try { // Detect the edges then strip out middle shades. grey = new ConvolutionFilter(new SobelEdgeFilter(), true).Process2DFilter(image); grey = new BinaryThreshold(threshold).ProcessFilter(grey); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0); grey.Dispose(); newImage = new Bitmap(rectangle.Width, rectangle.Height); newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(newImage)) { graphics.DrawImage( image, new Rectangle(0, 0, rectangle.Width, rectangle.Height), rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, GraphicsUnit.Pixel); } // Reassign the image. image.Dispose(); image = newImage; } catch (Exception ex) { if (grey != null) { grey.Dispose(); } if (newImage != null) { newImage.Dispose(); } throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); } return image; }
/// <summary> /// Traces the edges of a given <see cref="Image"/>. /// </summary> /// <param name="source"> /// The source <see cref="Image"/>. /// </param> /// <param name="destination"> /// The destination <see cref="Image"/>. /// </param> /// <param name="threshold"> /// The threshold (between 0 and 255). /// </param> /// <returns> /// The a new instance of <see cref="Bitmap"/> traced. /// </returns> public static Bitmap Trace(Image source, Image destination, byte threshold = 0) { int width = source.Width; int height = source.Height; // Grab the edges converting to greyscale, and invert the colors. ConvolutionFilter filter = new ConvolutionFilter(new SobelEdgeFilter(), true); using (Bitmap temp = filter.Process2DFilter(source)) { destination = new InvertMatrixFilter().TransformImage(temp, destination); // Darken it slightly to aid detection destination = Adjustments.Brightness(destination, -5); } // Loop through and replace any colors more white than the threshold // with a transparent one. using (FastBitmap destinationBitmap = new FastBitmap(destination)) { Parallel.For( 0, height, y => { for (int x = 0; x < width; x++) { // ReSharper disable AccessToDisposedClosure Color color = destinationBitmap.GetPixel(x, y); if (color.B >= threshold) { destinationBitmap.SetPixel(x, y, Color.Transparent); } // ReSharper restore AccessToDisposedClosure } }); } // Darken it again to average out the color. destination = Adjustments.Brightness(destination, -5); return (Bitmap)destination; }