Java图片压缩
0
最近发现网站传的图片很多都是直接使用相机照的,很多图片都非常大,这样占用空间,而且用户加载也会变慢,所以搞了一下压缩图片的方法。
但是网上很多都只有JPG的压缩方式,PNG的很少,这里也记录一下。
我们用PS把PNG转为网络图片我们一般会讲PNG24
转为PNG8
,这里也是我的思路,下面贴上代码:
public static final String PNG_EXTENSION = "png";
public static final String JPG_EXTENSION = "jpg";
public static boolean compress(String filePath) {
File file = StringUtils.isEmpty(filePath) ? null : new File(filePath);
if(!file.exists() || !file.isFile()) {
return false;
}
Graphics2D graphics2D = null;
ImageWriter imageWriter = null;
ImageWriteParam imageWriteParams = null;
FileOutputStream fileOutputStream = null;
try {
String extension = Tools.getFileExt(filePath);
imageWriter = ImageIO.getImageWritersByFormatName(extension).next();
if(PNG_EXTENSION.equals(extension.toLowerCase())) {
BufferedImage srcBufferedImage = ImageIO.read(file);
int width = srcBufferedImage.getWidth();
int height = srcBufferedImage.getHeight();
BufferedImage newBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_555_RGB);
graphics2D = newBufferedImage.createGraphics();
graphics2D.setBackground(BACKGROUND_COLOR);
graphics2D.clearRect(0, 0, width, height);
graphics2D.drawImage(srcBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
imageWriter = ImageIO.getImageWritersByFormatName(extension).next();
fileOutputStream = new FileOutputStream(filePath);
imageWriter.setOutput(ImageIO.createImageOutputStream(fileOutputStream));
imageWriter.write(new IIOImage(newBufferedImage, null, null));
fileOutputStream.flush();
} else if(JPG_EXTENSION.equals(extension.toLowerCase())) {
BufferedImage srcBufferedImage = ImageIO.read(new File(filePath));
imageWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
imageWriteParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParams.setCompressionQuality(0.8F);
imageWriteParams.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
ColorModel colorModel = ImageIO.read(new File(filePath)).getColorModel();
imageWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
fileOutputStream = new FileOutputStream(file);
imageWriter.setOutput(ImageIO.createImageOutputStream(fileOutputStream));
imageWriter.write(null, new IIOImage(srcBufferedImage, null, null), imageWriteParams);
fileOutputStream.flush();
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if(imageWriter != null)
imageWriter.abort();
IOUtils.closeQuietly(fileOutputStream);
}
return true;
}
下面是PNG的几种模式的对比TYPE_USHORT_555_RGB
,TYPE_INT_RGB
(这个相当于PNG24),TYPE_BYTE_INDEXED
(相当于PNG8)。
原始图片:411KB
TYPE_BYTE_INDEXED
处理后:139KB
TYPE_USHORT_555_RGB
处理后:218KB
TYPE_INT_RGB
处理后:532KB
PS处理后:127KB
仔细看原始图片和TYPE_INT_RGB
是最好的,其次是TYPE_USHORT_555_RGB
,然后是PS,最后是TYPE_BYTE_INDEXED
,仔细看丝袜部分,能看出来。考虑到大小和质量所以使用TYPE_USHORT_555_RGB
。
参考文章:
http://fandayrockworld.iteye.com/blog/628551
http://blog.csdn.net/monitor1394/article/details/6087583
注:这里主要处理PNG和JPG的图片,其他图片很少也不处理。
还有就是一般都是RGB的颜色,有的PS的CMYK模式的会出问题。
还有就是Tools.getFileExt(filePath);
这个是获取图片真实的格式,有的图片是PNG的格式但是却把后缀写成了JPG,这里防止这样的问题出现,具体问题参考文章:http://www.acgist.com/article/134.html