diff options
| author | Mike Wey | 2011-08-21 19:56:53 +0200 |
|---|---|---|
| committer | Mike Wey | 2011-08-21 19:56:53 +0200 |
| commit | 38b47ebbaff4326800286b2a93579298be6578c6 (patch) | |
| tree | 3a1af4e91f3b8c00f9a567437f49148dc2f6708f /dmagick/ColorCMYK.d | |
| parent | c1d158781cc242922663d12c4ad2ea6316093e65 (diff) | |
Add dmagick.ColorCMYK
Diffstat (limited to 'dmagick/ColorCMYK.d')
| -rw-r--r-- | dmagick/ColorCMYK.d | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/dmagick/ColorCMYK.d b/dmagick/ColorCMYK.d new file mode 100644 index 0000000..783ffb1 --- /dev/null +++ b/dmagick/ColorCMYK.d @@ -0,0 +1,175 @@ +/** + * Copyright: Mike Wey 2011 + * License: zlib (See accompanying LICENSE file) + * Authors: Mike Wey + */ + +module dmagick.ColorCMYK; + +import std.algorithm; + +import dmagick.Color; + +import dmagick.c.magickType; +import dmagick.c.quantum; + +/** + * The CMY(K) color model describes a color space with subtractive color + * composition as it is used for the color printing process, e.g. used by + * ink or laser printers. Each color is described by the color components + * cyan (C), magenta (M) and yellow (Y). The additional component black (K) + * is used for better gray and black reproduction. + * + * Note: This class doesn't use ICC or ICM profiles for the converson of + * CMYK to RGB. + */ +class ColorCMYK : Color +{ + this() + { + super(); + } + + /** + * Create a CMYK Color from the specified doubles. + */ + this(double cyan, double magenta, double yellow, double black) + { + Quantum red, green, blue; + + convertCMYKToRGB(cyan, magenta, yellow, black, red, green, blue); + + super(red, green, blue); + } + + /** + * The value for cyan. + */ + void cyan(double cyan) + { + double oldCyan, magenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, oldCyan, magenta, yellow, black); + convertCMYKToRGB(cyan, magenta, yellow, black, pixelPacket.red, pixelPacket.green, pixelPacket.blue); + } + ///ditto + double cyan() + { + double cyan, magenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, yellow, black); + + return cyan; + } + + /** + * The value for magenta. + */ + void magenta(double magenta) + { + double cyan, oldMagenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, oldMagenta, yellow, black); + convertCMYKToRGB(cyan, magenta, yellow, black, pixelPacket.red, pixelPacket.green, pixelPacket.blue); + } + ///ditto + double magenta() + { + double cyan, magenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, yellow, black); + + return magenta; + } + + /** + * The value for yellow. + */ + void yellow(double yellow) + { + double cyan, magenta, oldYellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, oldYellow, black); + convertCMYKToRGB(cyan, magenta, yellow, black, pixelPacket.red, pixelPacket.green, pixelPacket.blue); + } + ///ditto + double yellow() + { + double cyan, magenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, yellow, black); + + return yellow; + } + + /** + * The value for black. + */ + void black(double black) + { + double cyan, magenta, yellow, oldBlack; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, yellow, oldBlack); + convertCMYKToRGB(cyan, magenta, yellow, black, pixelPacket.red, pixelPacket.green, pixelPacket.blue); + } + ///ditto + double black() + { + double cyan, magenta, yellow, black; + + convertRGBToCMYK(pixelPacket.red, pixelPacket.green, pixelPacket.blue, cyan, magenta, yellow, black); + + return black; + } + + /** + * Convert an RGB value to a CMYK value. + */ + private void convertRGBToCMYK(Quantum red, Quantum green, Quantum blue, ref double cyan, ref double magenta, ref double yellow, ref double black) + { + double r = scaleQuantumToDouble(red); + double g = scaleQuantumToDouble(green); + double b = scaleQuantumToDouble(blue); + + black = min(1 - r, 1 - g, 1 - b); + + cyan = (1 - r - black) / (1 - black); + magenta = (1 - g - black) / (1 - black); + yellow = (1 - b - black) / (1 - black); + } + + /** + * Convert an CMYK value to a RGB value. + */ + private void convertCMYKToRGB(double cyan, double magenta, double yellow, double black, ref Quantum red, ref Quantum green, ref Quantum blue) + in + { + assert(cyan <= 1 && cyan >= 0); + assert(magenta <= 1 && magenta >= 0); + assert(yellow <= 1 && yellow >= 0); + assert(black <= 1 && black >= 0); + } + body + { + double r = 1 - min(1, cyan * (1 - black) + black); + double g = 1 - min(1, magenta * (1 - black) + black); + double b = 1 - min(1, yellow * (1 - black) + black); + + red = scaleDoubleToQuantum(r); + green = scaleDoubleToQuantum(g); + blue = scaleDoubleToQuantum(b); + } +} + +unittest +{ + assert(new ColorCMYK(0, 1, 1, 0 ) == new Color("red")); + + auto color1 = new ColorCMYK(0.5, 0.5, 0.5, 0.5); + auto color2 = new Color("gray25"); + + //Compare the colors a bytes, to compensate for rounding errors. + assert(ScaleQuantumToChar(color1.redQuantum) == ScaleQuantumToChar(color2.redQuantum)); + assert(ScaleQuantumToChar(color1.greenQuantum) == ScaleQuantumToChar(color2.greenQuantum)); + assert(ScaleQuantumToChar(color1.blueQuantum) == ScaleQuantumToChar(color2.blueQuantum)); +} |
