1 Reply Latest reply on Aug 3, 2015 10:44 AM by Jamo

    Reading CMYK jpeg images

    chandra12345

      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!!");

           }

       

        /**

        *

        * @param filePath

        * @param 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;

         

          /**

           *

           * @param 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;

          }

         

          /**

           *

           * @param 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;

                  }

              }

          }

         

          /**

           *

           * @param 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[x];

                      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[x] = 255 - c;

                      pixelRow[x + 1] = 255 - m;

                      pixelRow[x + 2] = 255 - y;

                  }

       

       

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

              }

          }

         

          /**

           *

           * @param 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[x] = 255 - pixelRow[x];

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

              }

          }

         

          /**

           *

           * @param cmykRaster

           * @param 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;

          }

       

       

       

       

      /**

      *

      * @param value

      * @param array

      * @param 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);

      }

      }

        • 1. Re: Reading CMYK jpeg images
          Jamo Level 2

          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#">