参考博文:
http://blog.csdn.net/kobejayandy/article/details/44346809
http://blog.csdn.net/shixing_11/article/details/6897871
http://blog.csdn.net/cuihailiang/article/details/52037389
问题现象:
Java上传图片时,对某些图片进行缩放、裁剪或者生成缩略图时会蒙上一层红色,经过检查只要经过ImageIO.read()方法读取后再保存,该图片便已经变成红图。因此,可以推测直接原因在于ImageIO.read()方法加载图片的过程存在问题。
1 public static BufferedImage getImages(byte[] data) throws IOException { 2 ByteArrayInputStream input = new ByteArrayInputStream(data); 3 return ImageIO.read(input); 4 }
经过查阅得知ImageIO.read()方法读取图片时可能存在不正确处理图片ICC信息的问题,ICC为JPEG图片格式中的一种头部信息,导致渲染图片前景色时蒙上一层红色。
解决方案:
1、使用awt Toolkit
不再使用ImageIO.read()方法加载图片,而使用JDK中提供的Image src=Toolkit.getDefaultToolkit().getImage
Image src = Toolkit.getDefaultToolkit().getImage(file.getPath()); BufferedImage image = BufferedImageBuilder.toBufferedImage(src);//Image to BufferedImage
或者Toolkit.getDefaultToolkit().createImage
1 Image imageTookit = Toolkit.getDefaultToolkit().createImage(bytes); 2 BufferedImage cutImage = BufferedImageBuilder.toBufferedImage(imageTookit);
BufferedImageBuilder源码:
public static BufferedImage toBufferedImage(Image image) { if (image instanceof BufferedImage) { return (BufferedImage) image; } // This code ensures that all the pixels in the image are loaded image = new ImageIcon(image).getImage(); BufferedImage bimage = null; GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); try { int transparency = Transparency.OPAQUE; GraphicsDevice gs = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gs.getDefaultConfiguration(); bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency); } catch (HeadlessException e) { // The system does not have a screen } if (bimage == null) { // Create a buffered image using the default color model int type = BufferedImage.TYPE_INT_RGB; bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type); } // Copy image to buffered image Graphics g = bimage.createGraphics(); // Paint the image onto the buffered image g.drawImage(image, 0, 0, null); g.dispose(); return bimage; }
如果该方法在Windows平台下使用正常,而在Linux平台上总是报异常,这种解决方式可以参考:http://blog.csdn.net/shixing_11/article/details/6897871/
2、使用阿里巴巴的SImpleImage
主要依赖以下jar包:commons-io-2.4.jar、commons-lang.jar、commons-logging-1.1.1.jar、jai_codec-1.1.3.jar、jai_core-1.1.3.jar
SimpleImage github地址:https://github.com/alibaba/simpleimage
相关jar包下载:http://download.csdn.net/detail/asd1231510/8911263
测试代码:
1 package com.sup.test; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 7 import org.apache.commons.io.IOUtils; 8 9 import com.alibaba.simpleimage.ImageRender; 10 import com.alibaba.simpleimage.SimpleImageException; 11 import com.alibaba.simpleimage.render.ReadRender; 12 import com.alibaba.simpleimage.render.ScaleParameter; 13 import com.alibaba.simpleimage.render.ScaleRender; 14 import com.alibaba.simpleimage.render.WriteRender; 15 16 public class Example { 17 18 public static void compressPicAlibaba (String srcFilePath, String descFilePath) { 19 File in = new File(srcFilePath); //原图片 20 File out = new File(descFilePath); //目的图片 21 ScaleParameter scaleParam = new ScaleParameter(); 22 23 FileInputStream inStream = null; 24 FileOutputStream outStream = null; 25 WriteRender wr = null; 26 try { 27 inStream = new FileInputStream(in); 28 outStream = new FileOutputStream(out); 29 ImageRender rr = new ReadRender(inStream); 30 ImageRender sr = new ScaleRender(rr, scaleParam); 31 wr = new WriteRender(sr, outStream); 32 33 wr.render(); //触发图像处理 34 } catch(Exception e) { 35 e.printStackTrace(); 36 } finally { 37 IOUtils.closeQuietly(inStream); //图片文件输入输出流必须记得关闭 38 IOUtils.closeQuietly(outStream); 39 if (wr != null) { 40 try { 41 wr.dispose(); //释放simpleImage的内部资源 42 } catch (SimpleImageException ignore) { 43 // skip ... 44 } 45 } 46 } 47 } 48 49 public static void main(String[] args) { 50 51 String srcFilePath = "F:\qw.jpg"; 52 String descFilePath = "F:\qw2.jpg"; 53 compressPicAlibaba(srcFilePath, descFilePath); 54 55 } 56 57 }