Browse Source

Finished CMYK halftone

Former-commit-id: 6a28d88ca2a01f75efde52d98d971ee8882a9225
Former-commit-id: 4d13793f853779c5b79fae0002ddc3446eaf6cd8
pull/17/head
James South 11 years ago
parent
commit
2d9a5a6ee8
  1. 2
      src/ImageProcessor.Playground/Program.cs
  2. 13
      src/ImageProcessor/ImageFactory.cs
  3. 18
      src/ImageProcessor/Imaging/Filters/Artistic/HalftoneFilter.cs
  4. 50
      src/ImageProcessor/Processors/Halftone.cs

2
src/ImageProcessor.Playground/Program.cs

@ -108,7 +108,7 @@ namespace ImageProcessor.PlayGround
//.DetectEdges(new Laplacian3X3EdgeFilter(), true)
//.DetectEdges(new LaplacianOfGaussianEdgeFilter())
//.EntropyCrop()
.Halftone()
.Halftone(true)
//.Filter(MatrixFilters.Invert)
//.Contrast(50)
//.Filter(MatrixFilters.Comic)

13
src/ImageProcessor/ImageFactory.cs

@ -681,11 +681,20 @@ namespace ImageProcessor
return this;
}
public ImageFactory Halftone()
/// <summary>
/// Converts the current image to a CMYK halftone representation of that image.
/// </summary>
/// <param name="comicMode">
/// Whether to trace over the current image and add borders to add a comic book effect.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory Halftone(bool comicMode = false)
{
if (this.ShouldProcess)
{
Halftone halftone = new Halftone();
Halftone halftone = new Halftone { DynamicParameter = comicMode };
this.CurrentImageFormat.ApplyProcessor(halftone.ProcessImage, this);
}

18
src/ImageProcessor/Imaging/Filters/Artistic/HalftoneFilter.cs

@ -37,6 +37,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
/// <summary>
/// The angle of the yellow component in degrees.
/// </summary>
// ReSharper disable once RedundantDefaultMemberInitializer
private float yellowAngle = 0f;
/// <summary>
@ -184,7 +185,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
float max = this.distance;
// Bump up the keyline max so that black looks black.
float keylineMax = max + ((float)Math.Sqrt(2) * 1.5f);
float keylineMax = max + ((float)Math.Sqrt(2) * 1.44f);
// Color sampled process colours from Wikipedia pages.
// Keyline brush is declared separately.
@ -239,9 +240,11 @@ namespace ImageProcessor.Imaging.Filters.Artistic
Color color;
CmykColor cmykColor;
float brushWidth;
int offsetX = x - (d >> 1);
int offsetY = y - (d >> 1);
// Cyan
Point rotatedPoint = ImageMaths.RotatePoint(new Point(x, y), this.cyanAngle, center);
Point rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.cyanAngle, center);
int angledX = rotatedPoint.X;
int angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
@ -253,7 +256,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
}
// Magenta
rotatedPoint = ImageMaths.RotatePoint(new Point(x, y), this.magentaAngle, center);
rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.magentaAngle, center);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
@ -265,7 +268,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
}
// Yellow
rotatedPoint = ImageMaths.RotatePoint(new Point(x, y), this.yellowAngle, center);
rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.yellowAngle, center);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
@ -277,7 +280,7 @@ namespace ImageProcessor.Imaging.Filters.Artistic
}
// Keyline
rotatedPoint = ImageMaths.RotatePoint(new Point(x, y), this.keylineAngle, center);
rotatedPoint = ImageMaths.RotatePoint(new Point(offsetX, offsetY), this.keylineAngle, center);
angledX = rotatedPoint.X;
angledY = rotatedPoint.Y;
if (rectangle.Contains(new Point(angledX, angledY)))
@ -321,7 +324,10 @@ namespace ImageProcessor.Imaging.Filters.Artistic
Color keylinePixel = keylineBitmap.GetPixel(x, y);
CmykColor blended = cyanPixel.AddAsCmykColor(magentaPixel, yellowPixel, keylinePixel);
destinationBitmap.SetPixel(x, y, blended);
if (rectangle.Contains(new Point(x, y)))
{
destinationBitmap.SetPixel(x, y, blended);
}
// ReSharper restore AccessToDisposedClosure
}
});

50
src/ImageProcessor/Processors/Halftone.cs

@ -13,7 +13,6 @@ namespace ImageProcessor.Processors
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading.Tasks;
using ImageProcessor.Common.Exceptions;
@ -70,43 +69,48 @@ namespace ImageProcessor.Processors
int width = image.Width;
int height = image.Height;
Bitmap newImage = null;
//Bitmap edgeBitmap = null;
Bitmap edgeBitmap = null;
try
{
HalftoneFilter filter = new HalftoneFilter(5);
newImage = new Bitmap(image);
newImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
newImage = filter.ApplyFilter(newImage);
bool comicMode = this.DynamicParameter;
// Draw the edges.
//edgeBitmap = new Bitmap(width, height);
//edgeBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
//edgeBitmap = Trace(image, edgeBitmap, 120);
using (Graphics graphics = Graphics.FromImage(newImage))
if (comicMode)
{
// Overlay the image.
//graphics.DrawImage(edgeBitmap, 0, 0);
Rectangle rectangle = new Rectangle(0, 0, width, height);
// Draw an edge around the image.
//using (Pen blackPen = new Pen(Color.Black))
//{
// blackPen.Width = 4;
// graphics.DrawRectangle(blackPen, rectangle);
//}
// Draw the edges.
edgeBitmap = new Bitmap(width, height);
edgeBitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution);
edgeBitmap = Trace(image, edgeBitmap, 120);
using (Graphics graphics = Graphics.FromImage(newImage))
{
// Overlay the image.
graphics.DrawImage(edgeBitmap, 0, 0);
Rectangle rectangle = new Rectangle(0, 0, width, height);
// Draw an edge around the image.
using (Pen blackPen = new Pen(Color.Black))
{
blackPen.Width = 4;
graphics.DrawRectangle(blackPen, rectangle);
}
}
edgeBitmap.Dispose();
}
//edgeBitmap.Dispose();
image.Dispose();
image = newImage;
}
catch (Exception ex)
{
//if (edgeBitmap != null)
//{
// edgeBitmap.Dispose();
//}
if (edgeBitmap != null)
{
edgeBitmap.Dispose();
}
if (newImage != null)
{

Loading…
Cancel
Save