Skip to content

Commit

Permalink
PDFBOX-1851: improved CMYK color space conversion as proposed by John…
Browse files Browse the repository at this point in the history
… Hewson

git-svn-id: https://svn.apache.org/repos/asf/pdfbox/trunk@1559486 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
lehmi committed Jan 19, 2014
1 parent 626fa3f commit 2fe4afd
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 180 deletions.
11 changes: 11 additions & 0 deletions pdfbox/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<plugins>
Expand Down Expand Up @@ -138,6 +148,7 @@
<configuration>
<excludes>
<exclude>src/main/resources/org/apache/pdfbox/resources/cmap/*</exclude>
<exclude>src/main/resources/org/apache/pdfbox/resources/icc/*</exclude>
<exclude>src/test/resources/input/rendering/*.ai</exclude>
<exclude>src/test/resources/output/*</exclude>
<exclude>release.properties</exclude>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -211,24 +211,30 @@ else if (PDLab.NAME.equals(csName))
sMsg += "\nInterpretating as RGB";
break;
case 4: // CMYK
// do a rough conversion to RGB as I'm not getting the CMYK to work.
// http://www.codeproject.com/KB/applications/xcmyk.aspx
float r,
g,
b,
k;
k = components[3];
try
{
// try to use the default CMYK color profile
float[] rgb = PDDeviceCMYK.INSTANCE.getJavaColorSpace().toRGB(components);
cGuess = new Color(rgb[0], rgb[1], rgb[2]);
sMsg += "\nInterpretating as CMYK using default ICC profile";
}
catch (Exception e1)
{
// fallback to naive conversion to RGB
float r, g, b, k;
k = components[3];

r = components[0] * (1f - k) + k;
g = components[1] * (1f - k) + k;
b = components[2] * (1f - k) + k;
r = components[0] * (1f - k) + k;
g = components[1] * (1f - k) + k;
b = components[2] * (1f - k) + k;

r = (1f - r);
g = (1f - g);
b = (1f - b);
r = (1f - r);
g = (1f - g);
b = (1f - b);

cGuess = new Color(r, g, b);
sMsg += "\nInterpretating as CMYK";
cGuess = new Color(r, g, b);
sMsg += "\nInterpretating as CMYK without ICC profile";
}
break;
default:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@
*/
package org.apache.pdfbox.pdmodel.graphics.color;

import org.apache.pdfbox.io.IOUtils;
import org.apache.pdfbox.util.ResourceLoader;

import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.ColorModel;
import java.io.IOException;

import java.awt.Transparency;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;

import java.io.InputStream;
import java.util.Properties;

/**
* This class represents a CMYK color space.
*
* @author <a href="mailto:[email protected]">Ben Litchfield</a>
* @version $Revision: 1.6 $
*/
public class PDDeviceCMYK extends PDColorSpace
{
Expand All @@ -48,6 +53,28 @@ public class PDDeviceCMYK extends PDColorSpace
*/
public static final String ABBREVIATED_NAME = "CMYK";

/**
* The external resources
*/
private static Properties defaultProfile = new Properties();

static
{
try
{
ResourceLoader.loadProperties(
"org/apache/pdfbox/resources/PDDeviceCMYK.properties",
defaultProfile);
}
catch (IOException io)
{
throw new RuntimeException("Error loading resources", io);
}
}

/**
* Constructs a new PDDeviceCMYK object.
*/
private PDDeviceCMYK()
{
}
Expand Down Expand Up @@ -79,9 +106,25 @@ public int getNumberOfComponents() throws IOException
*
* @return A color space that can be used for Java AWT operations.
*/
protected ColorSpace createColorSpace()
protected ColorSpace createColorSpace() throws IOException
{
return new ColorSpaceCMYK();
ColorSpace colorSpace;
InputStream profile = null;
try
{
profile = ResourceLoader.loadResource(defaultProfile.getProperty("DeviceCMYK"));
if (profile == null)
{
throw new IOException("Default CMYK color profile cannot be opened");
}
ICC_Profile iccProfile = ICC_Profile.getInstance(profile);
colorSpace = new ICC_ColorSpace(iccProfile);
}
finally
{
IOUtils.closeQuietly(profile);
}
return colorSpace;
}

/**
Expand All @@ -93,18 +136,18 @@ protected ColorSpace createColorSpace()
*
* @throws IOException If there is an error creating the color model.
*/
public ColorModel createColorModel( int bpc ) throws IOException
public ColorModel createColorModel(int bpc) throws IOException
{

int[] nbBits = { bpc, bpc, bpc, bpc };
ComponentColorModel componentColorModel =
new ComponentColorModel( getJavaColorSpace(),
nbBits,
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE );
return componentColorModel;
ComponentColorModel componentColorModel =
new ComponentColorModel(getJavaColorSpace(),
nbBits,
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
return componentColorModel;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

###########################################################################

# Adobe Acrobat uses "U.S. Web Coated (SWOP) v2" as the default
# CMYK profile, however it is not available under an open license.
# Instead, the "ISO Coated v2 300% (basICColor)" is used, which
# is an open alternative to the "ISO Coated v2 300% (ECI)" profile.

DeviceCMYK=org/apache/pdfbox/resources/icc/ISOcoated_v2_300_bas.icc
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.apache.pdfbox.pdfparser.PDFStreamParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.graphics.color.ColorSpaceCMYK;
import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceCMYK;
import org.apache.pdfbox.util.PDFOperator;

import java.awt.Color;
Expand All @@ -38,7 +38,7 @@ public class TestPDPageContentStream extends TestCase {
public void testSetCmykColors() throws IOException, COSVisitorException {
PDDocument doc = new PDDocument();

ColorSpace colorSpace = new ColorSpaceCMYK();
ColorSpace colorSpace = PDDeviceCMYK.INSTANCE.getJavaColorSpace();

PDPage page = new PDPage();
doc.addPage(page);
Expand Down

0 comments on commit 2fe4afd

Please sign in to comment.