Browse Source

Mask now accepts position instructions

Former-commit-id: 8e40db9486bd08d8dcf2850604d3e5f40dfeaee1
Former-commit-id: 803d99ed0ff547a62870e458ef95e918f31cf93f
pull/17/head
James South 12 years ago
parent
commit
7bab72aeca
  1. 15
      src/ImageProcessor.Playground/Program.cs
  2. BIN
      src/ImageProcessor.Playground/images/input/mask2.png
  3. BIN
      src/ImageProcessor.Playground/images/input/mask3.png
  4. 11
      src/ImageProcessor/ImageFactory.cs
  5. 6
      src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs
  6. 2
      src/ImageProcessor/Imaging/Helpers/Effects.cs
  7. 8
      src/ImageProcessor/Imaging/Helpers/ImageMaths.cs
  8. 77
      src/ImageProcessor/Processors/Mask.cs

15
src/ImageProcessor.Playground/Program.cs

@ -49,8 +49,8 @@ namespace ImageProcessor.PlayGround
di.Create();
}
Image mask = Image.FromFile(Path.Combine(resolvedPath, "mask.png"));
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".png");
Image mask = Image.FromFile(Path.Combine(resolvedPath, "mask2.png"));
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".jpg");
//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png", ".tif");
foreach (FileInfo fileInfo in files)
@ -66,7 +66,7 @@ namespace ImageProcessor.PlayGround
{
using (ImageFactory imageFactory = new ImageFactory(true))
{
Size size = new Size(400, 0);
Size size = new Size(800, 0);
ResizeLayer layer = new ResizeLayer(size, ResizeMode.Max, AnchorPosition.Center, false);
//ContentAwareResizeLayer layer = new ContentAwareResizeLayer(size)
@ -78,16 +78,17 @@ namespace ImageProcessor.PlayGround
//.BackgroundColor(Color.White)
//.Resize(new Size((int)(size.Width * 1.1), 0))
//.ContentAwareResize(layer)
//.Constrain(size)
//.Mask(mask)
.Constrain(size)
.Mask(mask)
//.Format(new PngFormat())
//.BackgroundColor(Color.HotPink)
//.ReplaceColor(Color.FromArgb(255, 1, 107, 165), Color.FromArgb(255, 1, 165, 13), 80)
//.Resize(layer)
//.DetectEdges(new SobelEdgeFilter(), false)
//.DetectEdges(new LaplacianOfGaussianEdgeFilter())
.EntropyCrop()
//.EntropyCrop()
//.Filter(MatrixFilters.Invert)
//.Filter(MatrixFilters.Comic)
.Filter(MatrixFilters.Comic)
//.Filter(MatrixFilters.HiSatch)
//.Pixelate(8)
//.GaussianSharpen(10)

BIN
src/ImageProcessor.Playground/images/input/mask2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

BIN
src/ImageProcessor.Playground/images/input/mask3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

11
src/ImageProcessor/ImageFactory.cs

@ -671,20 +671,23 @@ namespace ImageProcessor
}
/// <summary>
/// Applies the given image mask to the current image. If the mask is not the same size as the image
/// it will be centered against the image.
/// Applies the given image mask to the current image.
/// </summary>
/// <param name="imageMask">
/// The image containing the mask to apply.
/// </param>
/// <param name="point">
/// The <see cref="Point"/> to place the mask if it not the same dimensions as the original image.
/// If no position is set, the mask will be centered within the image.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory Mask(Image imageMask)
public ImageFactory Mask(Image imageMask, Point? point = null)
{
if (this.ShouldProcess)
{
Mask mask = new Mask { DynamicParameter = imageMask };
Mask mask = new Mask { DynamicParameter = new Tuple<Image, Point?>(imageMask, point) };
this.CurrentImageFormat.ApplyProcessor(mask.ProcessImage, this);
}

6
src/ImageProcessor/Imaging/Filters/Photo/ComicMatrixFilter.cs

@ -92,12 +92,12 @@ namespace ImageProcessor.Imaging.Filters.Photo
// Create the pattern mask.
using (Graphics graphics = Graphics.FromImage(patternBitmap))
{
graphics.Clear(Color.Black);
graphics.Clear(Color.Transparent);
graphics.SmoothingMode = SmoothingMode.HighQuality;
for (int y = 0; y < image.Height; y += 8)
for (int y = 0; y < height; y += 8)
{
for (int x = 0; x < image.Width; x += 4)
for (int x = 0; x < width; x += 4)
{
graphics.FillEllipse(Brushes.White, x, y, 3, 3);
graphics.FillEllipse(Brushes.White, x + 2, y + 4, 3, 3);

2
src/ImageProcessor/Imaging/Helpers/Effects.cs

@ -155,7 +155,7 @@ namespace ImageProcessor.Imaging.Helpers
if (sourceColor.A != 0)
{
sourceBitmap.SetPixel(x, y, Color.FromArgb(maskColor.B, sourceColor.R, sourceColor.G, sourceColor.B));
sourceBitmap.SetPixel(x, y, Color.FromArgb(maskColor.A, sourceColor.R, sourceColor.G, sourceColor.B));
}
// ReSharper restore AccessToDisposedClosure

8
src/ImageProcessor/Imaging/Helpers/ImageMaths.cs

@ -145,10 +145,10 @@ namespace ImageProcessor.Imaging.Helpers
using (FastBitmap fastBitmap = new FastBitmap(bitmap))
{
topLeft.Y = getMinY(fastBitmap) + 1;
topLeft.X = getMinX(fastBitmap) + 1;
bottomRight.Y = getMaxY(fastBitmap);
bottomRight.X = getMaxX(fastBitmap);
topLeft.Y = getMinY(fastBitmap);
topLeft.X = getMinX(fastBitmap);
bottomRight.Y = getMaxY(fastBitmap) + 1;
bottomRight.X = getMaxX(fastBitmap) + 1;
}
return ImageMaths.GetBoundingRectangle(topLeft, bottomRight);

77
src/ImageProcessor/Processors/Mask.cs

@ -15,6 +15,7 @@ namespace ImageProcessor.Processors
using System.Drawing;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging.Colors;
using ImageProcessor.Imaging.Helpers;
/// <summary>
@ -63,30 +64,67 @@ namespace ImageProcessor.Processors
{
Bitmap newImage = null;
Bitmap mask = null;
Bitmap maskResized = null;
Bitmap maskCropped = null;
Bitmap maskPositioned = null;
Image image = factory.Image;
try
{
int width = image.Width;
int height = image.Height;
mask = new Bitmap(this.DynamicParameter);
Rectangle parent = new Rectangle(0, 0, width, height);
Rectangle child = new Rectangle(0, 0, mask.Width, mask.Height);
RectangleF centered = ImageMaths.CenteredRectangle(parent, child);
// Resize the mask to the size of the input image so that we can apply it.
maskResized = new Bitmap(width, height);
using (Graphics graphics = Graphics.FromImage(maskResized))
Tuple<Image, Point?> parameters = this.DynamicParameter;
mask = new Bitmap(parameters.Item1);
Point? position = parameters.Item2.HasValue ? parameters.Item2 : null;
if (mask.Size != image.Size)
{
graphics.Clear(Color.Transparent);
graphics.DrawImage(mask, new PointF(centered.X, centered.Y));
}
Rectangle parent = new Rectangle(0, 0, width, height);
Rectangle child = ImageMaths.GetFilteredBoundingRectangle(mask, 0, RgbaComponent.A);
maskCropped = new Bitmap(child.Width, child.Height);
// 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);
}
newImage = Effects.ApplyMask(image, maskResized);
// Now position the mask in an image of the same dimensions as the original.
maskPositioned = new Bitmap(width, height);
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();
}
mask.Dispose();
maskResized.Dispose();
image.Dispose();
image = newImage;
}
@ -97,9 +135,14 @@ namespace ImageProcessor.Processors
mask.Dispose();
}
if (maskResized != null)
if (maskCropped != null)
{
maskCropped.Dispose();
}
if (maskPositioned != null)
{
maskResized.Dispose();
maskPositioned.Dispose();
}
if (newImage != null)

Loading…
Cancel
Save