将RGB PNG转换为CMYK JPEG(使用ICC颜色配置文件)



我需要将png文件转换为CMYK JPEG。

在我的研究中,我发现了许多关于SO的文章描述了这个问题。我用BufferedImageColorConvertOp复制了这个答案。

我想出了这个小例子:

public static void main(final String[] args) throws IOException
{
    final String imageFile = "/tmp/page0.png";
    final BufferedImage pngImage = ImageIO.read(new File(imageFile));
    // convert PNG to JPEG
    // http://www.mkyong.com/java/convert-png-to-jpeg-image-file-in-java/
    final BufferedImage rgbImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
    rgbImage.createGraphics().drawImage(pngImage, 0, 0, Color.WHITE, null);
    // RGB to CMYK using ColorConvertOp
    // https://stackoverflow.com/questions/380678/how-to-set-icc-color-profile-in-java-and-change-colorspace/2804370#2804370
    final ICC_Profile ip = ICC_Profile.getInstance("icc/ISOcoated_v2_300_eci.icc");
    // final ICC_Profile ip = ICC_Profile.getInstance("icc/CoatedFOGRA27.icc");
    // final ICC_Profile ip = ICC_Profile.getInstance("icc/USWebUncoated.icc");
    final ColorConvertOp cco = new ColorConvertOp(new ICC_ColorSpace(ip), null);
    final BufferedImage cmykImage = cco.filter(rgbImage, null);
    // Write the result into an bytearray
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(cmykImage, "jpg", baos);
    baos.flush();
    final byte[] imageInByte = baos.toByteArray();
}

问题是,它导致了这个例外:

Exception in thread "main" javax.imageio.IIOException: Invalid argument to native writeImage
    at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
    at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1058)
    at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:360)
    at javax.imageio.ImageWriter.write(ImageWriter.java:615)
    at javax.imageio.ImageIO.doWrite(ImageIO.java:1612)
    at javax.imageio.ImageIO.write(ImageIO.java:1578)
    at ... .pdf.ReportGeneratorPublicContentTest.main(ReportGeneratorPublicContentTest.java:69)

Exception的消息没有帮助我。在这个线程中,他们说sun jdk或JAI会解决这个问题。

我尝试了apt-get install libjai-core-java和oracle JDK jdk1.7.0_51

@Christian Schneider:在我下载你的图像文件与CMYK JPEG链接后,我打开文件的属性。我看到的图像颜色空间仍然是RGB。这张图片没有转换成CMYK颜色。请看下面的链接:

如何将RGB图像转换为CMYK,反之亦然?

lovelywib的答案解决了这个问题

TYPE_3BYTE_BGR代替TYPE_INT_RGB解决了这个问题。

public static void main(String[] args) throws Exception
{
    final String imageFile = "/tmp/page0.png";
    final BufferedImage pngImage = ImageIO.read(new File(imageFile));
    // convert PNG to JPEG
    // http://www.mkyong.com/java/convert-png-to-jpeg-image-file-in-java/
    final BufferedImage rgbImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
    rgbImage.createGraphics().drawImage(pngImage, 0, 0, Color.WHITE, null);
    // RGB to CMYK using ColorConvertOp
    // http://stackoverflow.com/questions/380678/how-to-set-icc-color-profile-in-java-and-change-colorspace/2804370#2804370
    final ICC_Profile ip = ICC_Profile.getInstance("icc/USWebUncoated.icc");
    final ColorConvertOp cco = new ColorConvertOp(rgbImage.getColorModel().getColorSpace(), new ICC_ColorSpace(ip), null);
    final BufferedImage cmykImage = new BufferedImage(pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
    cco.filter(rgbImage, cmykImage);
    // Write the result into an bytearray
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(cmykImage, "JPEG", baos);
    baos.flush();
}
  • RGB PNG:https://raw.github.com/d0x/questions/master/stackoverflowPlayground/src/main/resources/so22298328/page0.png

  • CMYK JPEG: https://raw.github.com/d0x/questions/master/stackoverflowPlayground/src/main/resources/so22298328/page0.cmyk.jpg

  • Maven在GitHub的代码:https://github.com/d0x/questions/blob/master/stackoverflowPlayground/src/main/java/so22298328/Main.java

最新更新