参考博文:
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) throwsIOException {2 ByteArrayInputStream input = newByteArrayInputStream(data);3 returnImageIO.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 staticBufferedImage toBufferedImage(Image image) {if (image instanceofBufferedImage) {return(BufferedImage) image;
}//This code ensures that all the pixels in the image are loaded
image = newImageIcon(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();returnbimage;
}
如果该方法在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 packagecom.sup.test;2
3 importjava.io.File;4 importjava.io.FileInputStream;5 importjava.io.FileOutputStream;6
7 importorg.apache.commons.io.IOUtils;8
9 importcom.alibaba.simpleimage.ImageRender;10 importcom.alibaba.simpleimage.SimpleImageException;11 importcom.alibaba.simpleimage.render.ReadRender;12 importcom.alibaba.simpleimage.render.ScaleParameter;13 importcom.alibaba.simpleimage.render.ScaleRender;14 importcom.alibaba.simpleimage.render.WriteRender;15
16 public classExample {17
18 public static voidcompressPicAlibaba (String srcFilePath, String descFilePath) {19 File in = new File(srcFilePath); //原图片
20 File out = new File(descFilePath); //目的图片
21 ScaleParameter scaleParam = newScaleParameter();22
23 FileInputStream inStream = null;24 FileOutputStream outStream = null;25 WriteRender wr = null;26 try{27 inStream = newFileInputStream(in);28 outStream = newFileOutputStream(out);29 ImageRender rr = newReadRender(inStream);30 ImageRender sr = newScaleRender(rr, scaleParam);31 wr = newWriteRender(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 voidmain(String[] args) {50
51 String srcFilePath = "F:\\qw.jpg";52 String descFilePath = "F:\\qw2.jpg";53 compressPicAlibaba(srcFilePath, descFilePath);54
55 }56
57 }