maven依赖:
<dependency>
<groupId>com.madgag</groupId>
<artifactId>animated-gif-lib</artifactId>
<version>1.2</version>
</dependency>
尺寸压缩:
/** * @param imagePath 原图片路径地址,如:F:\\a.png * @param imgStyle 目标文件类型
* gif类型图片尺寸压缩
* @param width 目标文件宽
* @param height 目标文件高
* @param outputPath 输出文件路径(不带后缀),如:F:\\b,默认与原图片路径相同,为空时将会替代原文
* @throws IOException
*/
public static void zoomGifBySize(String imagePath,int width, int height, String outputPath) throws IOException {
//GIF需要特殊处理
GifDecoder decoder = new GifDecoder(); int status = decoder.read(imagePath);
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + imagePath + " error!");
}
//拆分一帧一帧的压缩之后合成
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(outputPath);
encoder.setRepeat(decoder.getLoopCount());
for (int i = 0; i < decoder.getFrameCount(); i++) {
encoder.setDelay(decoder.getDelay(i));
//设置播放延迟时间
BufferedImage bufferedImage = decoder.getFrame(i);
//获取每帧BufferedImage流
BufferedImage zoomImage = new BufferedImage(width, height, bufferedImage.getType());
Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
Graphics gc = zoomImage.getGraphics(); gc.setColor(Color.WHITE);
gc.drawImage(image, 0, 0, null);
encoder.addFrame(zoomImage);
}
encoder.finish();
File outFile = new File(outputPath);
BufferedImage image = ImageIO.read(outFile);
ImageIO.write(image, outFile.getName(), outFile);
}
质量压缩:
/**
* @param imagePath 原图片路径地址,如:F:\\a.png * @param imgStyle 目标文件类型
* @param quality 输出的图片质量,范围:0.0~1.0,1为最高质量。
* @param outputPath 输出文件路径(不带后缀),如:F:\\b,默认与原图片路径相同,为空时将会替代原文件
* @throws IOException
*/
public void zoomGifByQuality(String imagePath, float quality, String outputPath) throws IOException {
//GIF需要特殊处理
GifDecoder decoder = new GifDecoder();
int status = decoder.read(imagePath);
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + imagePath + " error!");
}
//拆分一帧一帧的压缩之后合成
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(outputPath);
//设置合成位置
encoder.setRepeat(decoder.getLoopCount());
//设置GIF重复次数
int frameCount = decoder.getFrameCount();
//获取GIF有多少个frame
for (int i = 0; i < frameCount; i++) {
encoder.setDelay(decoder.getDelay(i));
//设置GIF延迟时间
BufferedImage bufferedImage = decoder.getFrame(i);
//利用java SDK压缩BufferedImage
byte[] tempByte = zoomBufferedImageByQuality(bufferedImage, quality, outputPath);
ByteArrayInputStream in = new ByteArrayInputStream(tempByte);
BufferedImage zoomImage = ImageIO.read(in);
encoder.addFrame(zoomImage);// 合成
}
encoder.finish();
File outFile = new File(outputPath);
BufferedImage image = ImageIO.read(outFile);
ImageIO.write(image, outFile.getName(), outFile);
}
/**
* 压缩gif
* @param bufferedImage
* @param quality
* @param path
* @return
* @throws IOException
*/
public byte[] zoomBufferedImageByQuality(BufferedImage bufferedImage, float quality, String path) throws IOException {
// 得到指定Format图片的writer
Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpeg");// 得到迭代器
ImageWriter writer = (ImageWriter) iter.next(); // 得到writer
// 得到指定writer的输出参数设置(ImageWriteParam)
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); // 设置可否压缩
iwp.setCompressionQuality(quality); // 设置压缩质量参数,0~1,1为最高质量
iwp.setProgressiveMode(ImageWriteParam.MODE_DISABLED);
ColorModel colorModel = ColorModel.getRGBdefault();
// 指定压缩时使用的色彩模式
iwp.setDestinationType(new ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(16, 16)));
// 开始打包图片,写入byte[]
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 取得内存输出流
IIOImage iIamge = new IIOImage(bufferedImage, null, null);
// 此处因为ImageWriter中用来接收write信息的output要求必须是ImageOutput
// 通过ImageIo中的静态方法,得到byteArrayOutputStream的ImageOutput
writer.setOutput(ImageIO.createImageOutputStream(byteArrayOutputStream));
writer.write(null, iIamge, iwp);
// 获取压缩后的btye
byte[] tempByte = byteArrayOutputStream.toByteArray();
// 创建输出文件,outputPath输出文件路径,imgStyle目标文件格式(png)
File outFile = new File(path);
FileOutputStream fos = new FileOutputStream(outFile);
fos.write(tempByte);
fos.close();
return tempByte;
}