我需要将PNG文件转换为CMYK JPEG。
在我的研究过程中,我发现了多篇关于SO的文章来描述这个问题。我使用BufferedImage
和ColorConvertOp
复制了this answer。
我想出了这个小例子:
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的消息对我没有帮助。在this thread,他们说sun jdk或JAI将解决这个问题。
我尝试了apt-get install libjai-core-java
和oracle JDK jdk1.7.0_51
。错误仍然存在。
答案 0 :(得分:0)
@Christian Schneider: 下载带有CMYK JPEG链接的图像文件后,我打开文件的属性。我看到图像的色彩空间仍然是RGB。此图片未转换为CMYK颜色。 请参阅以下链接:
how can I convert an RGB image to CMYK and vice versa in Java?
lovelywib的答案解决了这个问题。
答案 1 :(得分:-1)
使用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();
}