/// <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; var image = factory.Image; byte threshold = 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 var rectangle = ImageMaths.GetFilteredBoundingRectangle(grey, 0); grey.Dispose(); newImage = new Bitmap(rectangle.Width, rectangle.Height, PixelFormat.Format32bppPArgb); newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (var 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 " + 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); }
/// <inheritdoc/> protected override void OnApply(ImageBase <TColor, TPacked> target, ImageBase <TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle) { ImageBase <TColor, TPacked> temp = new Image <TColor, TPacked>(source.Width, source.Height); // Detect the edges. new SobelProcessor <TColor, TPacked>().Apply(temp, source, sourceRectangle); // Apply threshold binarization filter. new BinaryThresholdProcessor <TColor, TPacked>(.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; }
/// <inheritdoc/> protected override void BeforeImageApply(Image <TPixel> source, Rectangle sourceRectangle, Configuration configuration) { Rectangle rectangle; // All frames have be the same size so we only need to calculate the correct dimensions for the first frame using (ImageFrame <TPixel> temp = source.Frames.RootFrame.Clone()) { configuration = configuration ?? source.GetConfiguration(); // Detect the edges. new SobelProcessor <TPixel>(false).Apply(temp, sourceRectangle, configuration); // Apply threshold binarization filter. new BinaryThresholdProcessor <TPixel>(this.Threshold).Apply(temp, sourceRectangle, configuration); // Search for the first white pixels rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); } new CropProcessor <TPixel>(rectangle, source.Size()).Apply(source, sourceRectangle, configuration); }
/// <inheritdoc/> protected override void OnApply(ImageBase <TPixel> source, Rectangle sourceRectangle) { using (ImageBase <TPixel> temp = new Image <TPixel>(source)) { // Detect the edges. new SobelProcessor <TPixel>().Apply(temp, sourceRectangle); // Apply threshold binarization filter. new BinaryThresholdProcessor <TPixel>(this.Value).Apply(temp, sourceRectangle); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); if (rectangle == sourceRectangle) { return; } new CropProcessor <TPixel>(rectangle).Apply(source, sourceRectangle); } }
/// <inheritdoc/> protected override void OnApply(ImageBase <TColor, TPacked> source, Rectangle sourceRectangle) { ImageBase <TColor, TPacked> temp = new Image <TColor, TPacked>(source.Width, source.Height); temp.ClonePixels(source.Width, source.Height, source.Pixels); // Detect the edges. new SobelProcessor <TColor, TPacked>().Apply(temp, sourceRectangle); // Apply threshold binarization filter. new BinaryThresholdProcessor <TColor, TPacked>(this.Value).Apply(temp, sourceRectangle); // Search for the first white pixels Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); if (rectangle == sourceRectangle) { return; } new CropProcessor <TColor, TPacked>(rectangle).Apply(source, sourceRectangle); }
/// <inheritdoc/> protected override void BeforeImageApply() { Rectangle rectangle; // TODO: This is clunky. We should add behavior enum to ExtractFrame. // All frames have be the same size so we only need to calculate the correct dimensions for the first frame using (var temp = new Image <TPixel>(this.Configuration, this.Source.Metadata.DeepClone(), new[] { this.Source.Frames.RootFrame.Clone() })) { Configuration configuration = this.Source.GetConfiguration(); // Detect the edges. new SobelProcessor(false).Apply(temp, this.SourceRectangle); // Apply threshold binarization filter. new BinaryThresholdProcessor(this.definition.Threshold).Apply(temp, this.SourceRectangle); // Search for the first white pixels rectangle = ImageMaths.GetFilteredBoundingRectangle(temp.Frames.RootFrame, 0); } new CropProcessor(rectangle, this.Source.Size()).Apply(this.Source, this.SourceRectangle); base.BeforeImageApply(); }
/// <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 mask = null; Bitmap maskCropped = null; Bitmap maskPositioned = null; var image = factory.Image; try { var width = image.Width; var height = image.Height; ImageLayer parameters = DynamicParameter; mask = new Bitmap(parameters.Image); mask.SetResolution(image.HorizontalResolution, image.VerticalResolution); var position = parameters.Position; if (mask.Size != image.Size) { var parent = new Rectangle(0, 0, width, height); var child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A); maskCropped = new Bitmap(child.Width, child.Height, PixelFormat.Format32bppPArgb); maskCropped.SetResolution(image.HorizontalResolution, image.VerticalResolution); // First crop any bounding transparency. using (var graphics = Graphics.FromImage(maskCropped)) { GraphicsHelper.SetGraphicsOptions(graphics); graphics.Clear(Color.Transparent); graphics.DrawImage( mask, new Rectangle(0, 0, child.Width, child.Height), child.X, child.Y, child.Width, child.Height, GraphicsUnit.Pixel); } // Now position the mask in an image of the same dimensions as the original. maskPositioned = new Bitmap(width, height, PixelFormat.Format32bppPArgb); maskPositioned.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (var graphics = Graphics.FromImage(maskPositioned)) { GraphicsHelper.SetGraphicsOptions(graphics, true); graphics.Clear(Color.Transparent); if (position != null) { // Apply the mask at the given position. graphics.DrawImage(maskCropped, position.Value); } else { // Center it instead var centered = ImageMaths.CenteredRectangle(parent, child); graphics.DrawImage(maskCropped, new PointF(centered.X, centered.Y)); } } newImage = Effects.ApplyMask(image, maskPositioned); maskCropped.Dispose(); maskPositioned.Dispose(); } else { newImage = Effects.ApplyMask(image, mask); mask.Dispose(); } image.Dispose(); image = newImage; } catch (Exception ex) { mask?.Dispose(); maskCropped?.Dispose(); maskPositioned?.Dispose(); newImage?.Dispose(); throw new ImageProcessingException("Error processing image with " + 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 mask = null; Bitmap maskCropped = null; Bitmap maskPositioned = null; Image image = factory.Image; try { int width = image.Width; int height = image.Height; Tuple <Image, Point?> parameters = this.DynamicParameter; mask = new Bitmap(parameters.Item1); Point?position = parameters.Item2.HasValue ? parameters.Item2 : null; if (mask.Size != image.Size) { Rectangle parent = new Rectangle(0, 0, width, height); Rectangle child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A); maskCropped = new Bitmap(child.Width, child.Height); maskCropped.SetResolution(image.HorizontalResolution, image.VerticalResolution); // First crop any bounding transparency. using (Graphics graphics = Graphics.FromImage(maskCropped)) { graphics.Clear(Color.Transparent); graphics.DrawImage( mask, new Rectangle(0, 0, child.Width, child.Height), child.X, child.Y, child.Width, child.Height, GraphicsUnit.Pixel); } // Now position the mask in an image of the same dimensions as the original. maskPositioned = new Bitmap(width, height); maskPositioned.SetResolution(image.HorizontalResolution, image.VerticalResolution); using (Graphics graphics = Graphics.FromImage(maskPositioned)) { graphics.Clear(Color.Transparent); if (position != null) { // Apply the mask at the given position. graphics.DrawImage(maskCropped, position.Value); } else { // Center it instead RectangleF centered = ImageMaths.CenteredRectangle(parent, child); graphics.DrawImage(maskCropped, new PointF(centered.X, centered.Y)); } } newImage = Effects.ApplyMask(image, maskPositioned); maskCropped.Dispose(); maskPositioned.Dispose(); } else { newImage = Effects.ApplyMask(image, mask); mask.Dispose(); } image.Dispose(); image = newImage; } catch (Exception ex) { if (mask != null) { mask.Dispose(); } if (maskCropped != null) { maskCropped.Dispose(); } if (maskPositioned != null) { maskPositioned.Dispose(); } if (newImage != null) { newImage.Dispose(); } throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex); } return(image); }