项目为了降低存储生成,需要将图片质量压缩大小不变,并且全程要在内存中进行,所以我写了下面的方法。方法中传入参数有两个一个是图片的byte数组,一个是压缩质量(压缩质量在0-1之间)。处理完毕后会返回一个新的byte数组出来
/**
* 图片压缩质量然后返回一个byte数组
*
* @param imageByte 图片byte数组
* @param quality 压缩质量,在0-1之间,
* @return 返回的字节数组
*/
public static byte[] compressPicture(byte[] imageByte, float quality) throws IOException {
ByteArrayInputStream byteInput = new ByteArrayInputStream(imageByte); //将byte数组转换成byte输入流
BufferedImage image = ImageIO.read(byteInput); //将输入流,变成图片流
// 如果图片空,返回空
if (image == null) return null;
// 得到指定Format图片的writer
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");// 得到迭代器
ImageWriter writer = (ImageWriter) iter.next(); // 得到writer
// 得到指定writer的输出参数设置(ImageWriteParam )
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
iwp.setCompressionQuality(quality); // 设置压缩质量参数
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
ColorModel colorModel = ColorModel.getRGBdefault();
// 指定压缩时使用的色彩模式
iwp.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
// 开始打包图片,写入byte[]
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流
IIOImage iIamge = new IIOImage(image, null, null);
try {
// 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
// 通过ImageIo中的静态方法,得到byteArrayOutputStream的ImageOutput
writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
writer.write(null, iIamge, iwp);
} catch (IOException e) {
return null;
} finally {
StreamClose.close(byteInput,byteArrayOutputStream);
}
return byteArrayOutputStream.toByteArray();
}