Author: tilman Date: Thu Jul 3 15:31:35 2014 New Revision: 1607674 URL: http://svn.apache.org/r1607674 Log: PDFBOX-1997: don't use scaling in single conversion, but in raster conversion for LAB color space
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDCIEBasedColorSpace.java pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDCIEBasedColorSpace.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDCIEBasedColorSpace.java?rev=1607674&r1=1607673&r2=1607674&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDCIEBasedColorSpace.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDCIEBasedColorSpace.java Thu Jul 3 15:31:35 2014 @@ -33,6 +33,7 @@ public abstract class PDCIEBasedColorSpa // // WARNING: this method is performance sensitive, modify with care! // + @Override public BufferedImage toRGBImage(WritableRaster raster) throws IOException { // This method calls toRGB to convert images one pixel at a time. For matrix-based Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java?rev=1607674&r1=1607673&r2=1607674&view=diff ============================================================================== --- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java (original) +++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDLab.java Thu Jul 3 15:31:35 2014 @@ -23,6 +23,9 @@ import org.apache.pdfbox.cos.COSFloat; import org.apache.pdfbox.cos.COSName; import org.apache.pdfbox.pdmodel.common.PDRange; import java.awt.color.ColorSpace; +import java.awt.image.BufferedImage; +import java.awt.image.WritableRaster; +import java.io.IOException; /** * A Lab colour space is a CIE-based ABC colour space with two transformation stages. @@ -34,7 +37,7 @@ public final class PDLab extends PDCIEBa { private static final ColorSpace CIEXYZ = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ); - private COSDictionary dictionary; + private final COSDictionary dictionary; private PDColor initialColor; // we need to cache whitepoint values, because using getWhitePoint() @@ -77,30 +80,69 @@ public final class PDLab extends PDCIEBa return COSName.LAB.getName(); } + // + // WARNING: this method is performance sensitive, modify with care! + // @Override - public float[] toRGB(float[] value) + public BufferedImage toRGBImage(WritableRaster raster) throws IOException { + int width = raster.getWidth(); + int height = raster.getHeight(); + + BufferedImage rgbImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + WritableRaster rgbRaster = rgbImage.getRaster(); + float minA = getARange().getMin(); float maxA = getARange().getMax(); float minB = getBRange().getMin(); float maxB = getBRange().getMax(); - // scale to range - float l = value[0] * 100; - float a = minA + (value[1] * (maxA - minA)); - float b = minB + (value[2] * (maxB - minB)); + // always three components: ABC + float[] abc = new float[3]; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + raster.getPixel(x, y, abc); + + // 0..255 -> 0..1 + abc[0] /= 255; + abc[1] /= 255; + abc[2] /= 255; + + // scale to range + abc[0] *= 100; + abc[1] = minA + (abc[1] * (maxA - minA)); + abc[2] = minB + (abc[2] * (maxB - minB)); + + float[] rgb = toRGB(abc); + + // 0..1 -> 0..255 + rgb[0] *= 255; + rgb[1] *= 255; + rgb[2] *= 255; + + rgbRaster.setPixel(x, y, rgb); + } + } + + return rgbImage; + } + @Override + public float[] toRGB(float[] value) + { // CIE LAB to RGB, see http://en.wikipedia.org/wiki/Lab_color_space // L* - float lstar = (l + 16f) * (1f / 116f); + float lstar = (value[0] + 16f) * (1f / 116f); // TODO: how to use the blackpoint? scale linearly between black & white? // XYZ - float x = wpX * inverse(lstar + a * (1f / 500f)); + float x = wpX * inverse(lstar + value[1] * (1f / 500f)); float y = wpY * inverse(lstar); - float z = wpZ * inverse(lstar - b * (1f / 200f)); + float z = wpZ * inverse(lstar - value[2] * (1f / 200f)); // XYZ to RGB return CIEXYZ.toRGB(new float[] { x, y, z });