ImageIO.read()方法读取图片后重写,图片蒙上一层红色的解决办法

Java 新民 1836℃ 已收录 0评论

1.在项目中为了处理用户上传的图片,会对图片进行重写处理,故使用了类似下面的代码:

  1. File src = new File(“e:/img/google.jpg”);
  2. BufferedImage bi = (BufferedImage)ImageIO.read(src);
  3. BufferedImage bi_scale = new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB );
  4. Graphics2D g = bi_scale.createGraphics();
  5. g.drawImage( bi, 00, bi.getWidth(), bi.getHeight(), null );
  6. g.dispose();
  7. FileOutputStream fos = new FileOutputStream(“e:/img/google2.jpg”);
  8. ImageIO.write(bi_scale, “jpg”, fos);
  9. fos.close();

原图如下:

但发现对于CMYK模式的图片ImageIO.read方法在读取时,会丢失掉ICC信息,从面导致重写后的图片上面蒙受上一层红色如下:

显然对图片质量的影响非常大,在用户体验非常高的互联网上是没法让用户接受的,于是又改用另外一种获取Image对象的方法如下:

  1. Image image = Toolkit.getDefaultToolkit().getImage(“e:\img\google.jpg”);

但该方法在Windows平台下使用正常,而在Linux平台上总是报异常如下:

  1. java.awt.HeadlessException:
  2. No X11 DISPLAY variable was set, but this program performed an operation which requires it.
  3.         at sun.awt.HeadlessToolkit.getScreenSize(HeadlessToolkit.java:281)
  4.         at ScreenCapture.main(ScreenCapture.java:23)

然后按照网上的方法,运行的时候加了-Djava.awt.headless=true即 java -Djava.awt.headless=true ClassName 但接着报如下异常:

  1. java.awt.HeadlessException
  2. java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)
  3. java.awt.Window.<init>(Window.java:406)

原因是:Toolkit.getDefaultToolkit()方法中有一句

  1. 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信息的代码如下:

  1. ICC_Profile ICC_pf= ICC_Profile.getInstance( “e:/img/jaicmm/CMYK.pf”);
  2. ICC_ColorSpace ICC_ClSpace= new ICC_ColorSpace(ICC_pf);

其中*.pf色彩文件从http://java.sun.com/products/java-media/jai/downloads/download-1_0_2.html可取得。

本站文章如未注明,均为原创丨本网站采用BY-NC-SA协议进行授权,转载请注明转自:https://www.snowruin.com/?p=1369
喜欢 (0)or分享 (0)
发表我的评论
取消评论
表情 代码 贴图 加粗 链接 私信 删除线 签到

Hi,请填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址