转载至:http://blog.csdn.net/shixing_11/article/details/6897871
1.在项目中为了处理用户上传的图片,会对图片进行重写处理,故使用了类似下面的代码:
File src = new File("e:/img/google.jpg");
BufferedImage bi = (BufferedImage)ImageIO.read(src);
BufferedImage bi_scale = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB );
Graphics2D g = bi_scale.createGraphics();
g.drawImage( bi, 0, 0, bi.getWidth(), bi.getHeight(), null );
g.dispose();
FileOutputStream fos = new FileOutputStream("e:/img/google2.jpg");
ImageIO.write(bi_scale, "jpg", fos);
fos.close();
原图如下:
但发现对于CMYK模式的图片ImageIO.read方法在读取时,会丢失掉ICC信息,从面导致重写后的图片上面蒙受上一层红色如下:
显然对图片质量的影响非常大,在用户体验非常高的互联网上是没法让用户接受的,于是又改用另外一种获取Image对象的方法如下:
Image image = Toolkit.getDefaultToolkit().getImage("e:\img\google.jpg");
但该方法在Windows平台下使用正常,而在Linux平台上总是报异常如下:
java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at sun.awt.HeadlessToolkit.getScreenSize(HeadlessToolkit.java:281)
at ScreenCapture.main(ScreenCapture.java:23)
然后按照网上的方法,运行的时候加了-Djava.awt.headless=true即 java -Djava.awt.headless=true ClassName 但接着报如下异常:
java.awt.HeadlessException
java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
java.awt.Window.<init>(Window.java:406)
原因是:Toolkit.getDefaultToolkit()方法中有一句
str = System.getProperty("awt.toolkit", "sun.awt.X11.XToolkit");
其实这句话的意思是该程序运行需要有图片环境的支持,后来经过测试,在Linux开了图形窗口后运行也是正常的,但对于生产环境的服务器要开个图形界面是不太现实的,最终放弃了这种方案。经过探索在Linux下只能选用ImageMagick结合JMagick实现,此时能独立于X-11系统,请看下篇,ImageMagick,Jmagick-linux_64安装说明
注意:
1.使用Jimi1.0 版本,保存PICT文件格式时输出的图像宽、高和内存中的图像源一致,可是显示出来却是纯白的。这是 Jimi1.0 版本对写Pict格式的一处 BUG,下载了新的补订类PICTWriter.java 重新编译成PICTWriter.class加入 JimiProClasses.zip 中覆盖原有的 PICTWriter.class,遂写 PICT 格式成功。可以参考官方说明:http://amug.org/~glguerin/other/index.html#PICTWriter 编译时注意要兼容你的JDK版本。
2.关于ImageIO.read()方法读取图片时不能正确处理ICC信息的问题,一般这些图片,是由扫描仪扫描,或者数码相机拍摄,并且处理时,图片的颜色空间(colorspace)为CMYK模式,可以参考官方BUG说明:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6245283
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6404011
另外处理相关ICC信息的代码如下:
ICC_Profile ICC_pf= ICC_Profile.getInstance( "e:/img/jaicmm/CMYK.pf");
ICC_ColorSpace ICC_ClSpace= new ICC_ColorSpace(ICC_pf);
其中*.pf色彩文件从
http://java.sun.com/products/java-media/jai/downloads/download-1_0_2.html可取得。