How to preserve icc/rendering intent when converting image color space


I need to convert images that has lab color space into rgb or cmyk. The code I'm using is this:

ElementBuilder elementBuilder = new ElementBuilder();
ElementWriter elementWriter = new ElementWriter();
elementWriter.begin(page, ElementWriter.e_replacement, false);
if ((element.getType() == Element.e_image || element.getType() == Element.e_inline_image)) {
    if (element.getImageColorSpace().getType() == ColorSpace.e_lab) {
        Image2RGB image2rgb = new Image2RGB(element);
        FilterReader image_reader = new FilterReader(image2rgb);

        Image image = Image.create(pdfDoc, image_reader, element.getImageWidth(), element.getImageHeight(), 8, ColorSpace.createDeviceRGB());
        Element newElementImage = elementBuilder.createImage(image, element.getCTM());

It works, but new image has new rendering intent (e_relative_colorimetric) and I need to preserve original image rendering intent(perceptual).
What is proper way to do this? I do it like this:


Pdftron returns correct rendering intent for this new image, but Adobe Acrobat pro 9 Preflight doesn't show any rendering intent. In fact, it doesn't show any ICC for this image (original image had ICC). How do I preserve icc/copy icc from orig image to new one?
I tried with (to be used in Image.create):

ColorSpace iccFromFilter = ColorSpace.createICCFromFilter(pdfDoc, element.getImageData());

but I get error:

   Message: Bad ICC profile

   Conditional expression: prof.get()
   Filename : ColorSpace.cpp
   Function : trn::PDF::ColorSpace::CreateICC
   Linenumber : 72
   Error code : 0

Thanks for your help

After a little more digging I guess you can’t copy ICC. Now I’m loading it from file and pass it to Image.create()

Also I changed a convert function a little, previous one made a duplicate images in pdf if the converting image was the same on multiple pages and the resulting pdf got bigger.
New code, using JBIGTest sample:

SDFDoc cos_doc = pdfDoc.getSDFDoc();
int num_objs = (int)cos_doc.xRefSize();
for(int i=1; i<num_objs; ++i) {
Obj obj = cos_doc.getObj(i);
if (obj != null && !obj.isFree() && obj.isStream()) {
// Process only images
DictIterator itr = obj.find(“Subtype”);
if (!itr.hasNext() || !itr.value().getName().equals(“Image”))

Image orig_image = new Image(obj);
if (orig_image.getImageColorSpace().getType() == ColorSpace.e_lab) {

Image2RGB image2rgb = new Image2RGB(obj);
FilterReader image_reader = new FilterReader(image2rgb);

ColorSpace iccFromFile = ColorSpace.createICCFromFile(pdfDoc, “c:\temp\sRGB_v4_ICC_preference.icc”);

Image new_image = Image.create(cos_doc, image_reader,
orig_image.getImageHeight(), 8, iccFromFile);

Obj new_img_obj = new_image.getSDFObj();

cos_doc.swap(i, new_img_obj.getObjNum());

Q. How do I set image rendering intent? I don’t have element or gstate here to use GState.setrenderingIntent(). Converted image has e_relative_colorimetric and I need it to be perceptual.

Ha, it’s simple when you read pdf specs:

itr = obj.find(“Intent”);
new_img_obj.put(“Intent”, itr.value());