Skip to main content
Inspiring
July 31, 2015
Question

Reading CMYK jpeg images

  • July 31, 2015
  • 1 reply
  • 1069 views

Hi,

I am unable to read CMYK jpeg images from coldfusion 10. Below are my server configuration.

Coldfusion 10 (update 14),32 bit and windows 2008 r2 64 bit,jre(1.6)

i found below code in java and implemented in coldfusion,but the code is working fine in coldfusion 10 64 bit,but not coldfusion 32 bit.

Shall i get any help on this?

public class CMYKTiffToJpegConvertor {

  /**

  *

  */

  public CMYKTiffToJpegConvertor() {

  // TODO Auto-generated constructor stub

  }

  public static void main(String[] args) throws IOException, Exception

     {

  new CMYKTiffToJpegConvertor().processConvertionImage(ImageConstants.FILE_PATH,ImageConstants.INPUT_FILE_NAME);

  System.out.println("Successfully Completed the conversion!!");

     }

  /**

  *

  * @9397041 filePath

  * @9397041 fileName

  * @throws IOException

  * @throws Exception

  */

  public void processConvertionImage(String filePath,String fileName) throws IOException, Exception{

  fileName = filePath+fileName;

  BufferedImage img =  readImage(fileName);

  String milliSec = new String(""+new Date().getTime()+"_");

  String path = filePath+milliSec+ImageConstants.OUTPUT_FILE_NAME;

    ImageIO.write(img,"jpg", new File(path));

  }

  public static final int COLOR_TYPE_RGB = 1;

    public static final int COLOR_TYPE_CMYK = 2;

    public static final int COLOR_TYPE_YCCK = 3;

    private int colorType = COLOR_TYPE_RGB;

    private boolean hasAdobeMarker = false;

   

    /**

     *

     * @9397041 filename

     * @Return

     * @throws IOException

     * @throws ImageReadException

     */

    public BufferedImage readImage(String filename) throws IOException, ImageReadException {

        colorType = COLOR_TYPE_RGB;

        hasAdobeMarker = false;

        File imgfile = new File(filename);

        ImageInputStream stream = ImageIO.createImageInputStream(imgfile);

        Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);

        while (iter.hasNext()) {

            ImageReader reader = iter.next();

            reader.setInput(stream);

            BufferedImage image;

            ICC_Profile profile = null;

            try {

                image = reader.read(0);

            } catch (IIOException e) {

                colorType = COLOR_TYPE_CMYK;

                checkAdobeMarker(imgfile);

                profile = Sanselan.getICCProfile(imgfile);

                WritableRaster raster = (WritableRaster) reader.readRaster(0, null);

                if (colorType == COLOR_TYPE_YCCK)

                    convertYcckToCmyk(raster);

                if (hasAdobeMarker)

                    convertInvertedColors(raster);

                image = convertCmykToRgb(raster, profile);

            }

            return image;

        }

        return null;

    }

   

    /**

     *

     * @9397041 file

     * @throws IOException

     * @throws ImageReadException

     */

    public void checkAdobeMarker(File file) throws IOException, ImageReadException {

        JpegImageParser parser = new JpegImageParser();

       

        ByteSource byteSource = new ByteSourceFile(file);

        @SuppressWarnings("rawtypes")

        ArrayList segments = parser.readSegments(byteSource, new int[] { 0xffee }, true);

        if (segments != null && segments.size() >= 1) {

            UnknownSegment app14Segment = (UnknownSegment) segments.get(0);

            byte[] data = app14Segment.bytes;

            if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e')

            {

                hasAdobeMarker = true;

                int transform = app14Segment.bytes[11] & 0xff;

                if (transform == 2)

                    colorType = COLOR_TYPE_YCCK;

            }

        }

    }

   

    /**

     *

     * @9397041 raster

     */

    public static void convertYcckToCmyk(WritableRaster raster) {

        int height = raster.getHeight();

        int width = raster.getWidth();

        int stride = width * 4;

        int[] pixelRow = new int[stride];

        for (int h = 0; h < height; h++) {

            raster.getPixels(0, h, width, 1, pixelRow);

            for (int x = 0; x < stride; x += 4) {

                int y = pixelRow;

                int cb = pixelRow[x + 1];

                int cr = pixelRow[x + 2];

                int c = (int) (y + 1.402 * cr - 178.956);

                int m = (int) (y - 0.34414 * cb - 0.71414 * cr + 135.95984);

                y = (int) (y + 1.772 * cb - 226.316);

                if (c < 0) c = 0; else if (c > 255) c = 255;

                if (m < 0) m = 0; else if (m > 255) m = 255;

                if (y < 0) y = 0; else if (y > 255) y = 255;

                pixelRow = 255 - c;

                pixelRow[x + 1] = 255 - m;

                pixelRow[x + 2] = 255 - y;

            }

            raster.setPixels(0, h, width, 1, pixelRow);

        }

    }

   

    /**

     *

     * @9397041 raster

     */

    public static void convertInvertedColors(WritableRaster raster) {

        int height = raster.getHeight();

        int width = raster.getWidth();

        int stride = width * 4;

        int[] pixelRow = new int[stride];

        for (int h = 0; h < height; h++) {

            raster.getPixels(0, h, width, 1, pixelRow);

            for (int x = 0; x < stride; x++)

                pixelRow = 255 - pixelRow;

            raster.setPixels(0, h, width, 1, pixelRow);

        }

    }

   

    /**

     *

     * @9397041 cmykRaster

     * @9397041 cmykProfile

     * @Return

     * @throws IOException

     */

    public static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {

        if (cmykProfile == null)

            cmykProfile = ICC_Profile.getInstance(CMYKTiffToJpegConvertor.class.getResourceAsStream("/ISOcoated_v2_300_eci.icc"));

        if (cmykProfile.getProfileClass() != ICC_Profile.CLASS_DISPLAY) {

            byte[] profileData = cmykProfile.getData();

            if (profileData[ICC_Profile.icHdrRenderingIntent] == ICC_Profile.icPerceptual) {

                intToBigEndian(ICC_Profile.icSigDisplayClass, profileData, ICC_Profile.icHdrDeviceClass); // Header is first

                cmykProfile = ICC_Profile.getInstance(profileData);

            }

        }

        ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);

        BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);

        WritableRaster rgbRaster = rgbImage.getRaster();

        ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();

        ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);

        cmykToRgb.filter(cmykRaster, rgbRaster);

        return rgbImage;

    }

/**

*

* @9397041 value

* @9397041 array

* @9397041 index

*/

    public static void intToBigEndian(int value, byte[] array, int index) {

  array[index] = (byte) (value >> 24);

  array[index + 1] = (byte) (value >> 16);

  array[index + 2] = (byte) (value >> 8);

  array[index + 3] = (byte) (value);

}

}

    This topic has been closed for replies.

    1 reply

    James Moberg
    Inspiring
    August 3, 2015

    I gave up using ColdFusion-related image functions. I've still identified CMYK images that can't consistently be read by ColdFusion 10.  I also still have some apps running on ColdFusion 9 and needed a solution that was backwards compatible.

    I started using CFX_OpenImage, but it hasn't been updated in a while.  I recently wrote a ColdFusion Custom Tag to access GraphicsMagick.  It can be installed on pretty much any 32-bit or 64-bit operating system.  It supports 88 major formats including important formats like DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNM, and TIFF.  This method is faster than CFImage and often generates much smaller files.

    Here's the link to the custom tag if you are interested.:

    http://gamesover2600.tumblr.com/post/125766251344/graphicsmagick-coldfusion-custom-tag

    Converting any JPG to a non-CMYK JPG can be done by:
    <CF_GraphicsMagick action="Optimize" Infile="#ImageIn#">