Browse Source

Finished CMYK halftone

Former-commit-id: ad9bb35112f36f73d6237e96ca17348f17fb8e26
Former-commit-id: aa21bf2996acfea29d485c67a8ae19dce57d1e51
af/merge-core
James South 11 years ago
parent
commit
4a79dca642
  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 Laplacian3X3EdgeFilter(), true)
//.DetectEdges(new LaplacianOfGaussianEdgeFilter()) //.DetectEdges(new LaplacianOfGaussianEdgeFilter())
//.EntropyCrop() //.EntropyCrop()
.Halftone() .Halftone(true)
//.Filter(MatrixFilters.Invert) //.Filter(MatrixFilters.Invert)
//.Contrast(50) //.Contrast(50)
//.Filter(MatrixFilters.Comic) //.Filter(MatrixFilters.Comic)

13
src/ImageProcessor/ImageFactory.cs

@ -681,11 +681,20 @@ namespace ImageProcessor
return this; 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) if (this.ShouldProcess)
{ {
Halftone halftone = new Halftone(); Halftone halftone = new Halftone { DynamicParameter = comicMode };
this.CurrentImageFormat.ApplyProcessor(halftone.ProcessImage, this); this.CurrentImageFormat.ApplyProcessor(halftone.ProcessImage, this);
} }

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

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

50
src/ImageProcessor/Processors/Halftone.cs

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

Loading…
Cancel
Save