GIF压缩
gif压缩功能,网上找了很多方法不太行,最后参考了这些博客解决了压缩问题,主要自己记录下。
参考如下:
http://www.blogjava.net/wangxinsh55/archive/2016/05/23/430621.html
https://www.jianshu.com/p/f3051c4541e5
直接上
package com.whispark.common.exception;
import com.madgag.gif.fmsware.AnimatedGifEncoder;
import com.madgag.gif.fmsware.GifDecoder;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;
/**
* gif图片处理
* @Author Clint
* Date on 2020/6/9 18:24
* explain:
*/
public class IamgesResize {
/**
* 获取图片格式
* @param file 图片文件
* @return 图片格式
*/
public static String getImageFormatName(File file)throws IOException{
String formatName = null;
ImageInputStream iis = ImageIO.createImageInputStream(file);
Iterator<ImageReader> imageReader = ImageIO.getImageReaders(iis);
if(imageReader.hasNext()){
ImageReader reader = imageReader.next();
formatName = reader.getFormatName();
}
return formatName;
}
/**
* 剪切图片
*
* @param sourcePath 待剪切图片路径
* @param targetPath 裁剪后保存路径(默认为源路径)
* @param x 起始横坐标
* @param y 起始纵坐标
* @param width 剪切宽度
* @param height 剪切高度
*
* @returns 裁剪后保存路径(图片后缀根据图片本身类型生成)
* @throws IOException
*/
public static String cutImage(String sourcePath , String targetPath , int x , int y , int width , int height) throws IOException{
File file = new File(sourcePath);
if(!file.exists()) {
throw new IOException("not found the image:" + sourcePath);
}
if(null == targetPath || targetPath.isEmpty()) targetPath = sourcePath;
String formatName = getImageFormatName(file);
if(null == formatName) return targetPath;
formatName = formatName.toLowerCase();
// 防止图片后缀与图片本身类型不一致的情况
String pathPrefix = getPathWithoutSuffix(targetPath);
targetPath = pathPrefix + formatName;
// GIF需要特殊处理
if(IMAGE_FORMAT.GIF.getValue() == formatName){
GifDecoder decoder = new GifDecoder();
int status = decoder.read(sourcePath);
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + sourcePath + " error!");
}
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(targetPath);
encoder.setRepeat(decoder.getLoopCount());
for (int i = 0; i < decoder.getFrameCount(); i ++) {
encoder.setDelay(decoder.getDelay(i));
BufferedImage childImage = decoder.getFrame(i);
BufferedImage image = childImage.getSubimage(x, y, width, height);
encoder.addFrame(image);
}
encoder.finish();
}else{
BufferedImage image = ImageIO.read(file);
image = image.getSubimage(x, y, width, height);
ImageIO.write(image, formatName, new File(targetPath));
}
//普通图片
BufferedImage image = ImageIO.read(file);
image = image.getSubimage(x, y, width, height);
ImageIO.write(image, formatName, new File(targetPath));
return targetPath;
}
/**
* 压缩图片
* @param sourceImage 待压缩图片
* @param width 压缩图片高度
* @param height 压缩图片宽度
*/
private static BufferedImage zoom(BufferedImage sourceImage , int width , int height){
BufferedImage zoomImage = new BufferedImage(width, height, sourceImage.getType());
Image image = sourceImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
Graphics gc = zoomImage.getGraphics();
gc.setColor(Color.WHITE);
gc.drawImage( image , 0, 0, null);
return zoomImage;
}
/**
* 获取不包含后缀的文件路径
*
* @param src
* @return
*/
public static String getPathWithoutSuffix(String src){
String path = src;
int index = path.lastIndexOf(".");
if(index > 0){
path = path.substring(0, index + 1);
}
return path;
}
public enum IMAGE_FORMAT{
BMP("bmp"),
JPG("jpg"),
WBMP("wbmp"),
JPEG("jpeg"),
PNG("png"),
GIF("gif");
private String value;
IMAGE_FORMAT(String value){
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
/**
* 压缩图片
* @param sourcePath 待压缩的图片路径
* @param targetPath 压缩后图片路径(默认为初始路径)
* @param width 压缩宽度
* @param height 压缩高度
*
* @returns 裁剪后保存路径(图片后缀根据图片本身类型生成)
* @throws IOException
*/
public static String zoom(String sourcePath , String targetPath, int width , int height) throws IOException{
File file = new File(sourcePath);
boolean is = !file.exists();
if(is) {
throw new IOException("not found the image :" + sourcePath);
}
String targetImgPath = targetPath;
if(null == targetImgPath || targetImgPath.isEmpty()){
targetImgPath = targetPath;
}
String formatName = getImageFormatName(file);
if(null == formatName){
return targetImgPath;
}
formatName = formatName.toLowerCase();
// 防止图片后缀与图片本身类型不一致的情况
String pathPrefix = getPathWithoutSuffix(targetImgPath);
targetImgPath = pathPrefix + formatName;
// GIF需要特殊处理
if(IMAGE_FORMAT.GIF.getValue() == formatName){
GifDecoder decoder = new GifDecoder();
int status = decoder.read(file.getPath());
if (status != GifDecoder.STATUS_OK) {
throw new IOException("read image " + file.getPath() + " error!");
}
//gif处理工具类 AnimatedGifEncoder
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
encoder.start(targetImgPath);
//获取图片的帧数
encoder.setRepeat(decoder.getLoopCount());
//检测输出路径是否存在 否则创建
File file1 = new File(targetImgPath);
File parentFile = file1.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
//循环处理图片帧数
int imgCount = decoder.getFrameCount();
for (int i = 0; i < imgCount; i ++) {
encoder.setDelay(decoder.getDelay(i));
BufferedImage image = zoom(decoder.getFrame(i), width , height);
encoder.addFrame(image);
}
encoder.finish();
}else{
//其他图片压缩处理
BufferedImage image = ImageIO.read(file);
BufferedImage zoomImage = zoom(image , width , height);
ImageIO.write(zoomImage, formatName, new File(targetImgPath));
}
return targetPath;
}
}
最后还需要一个工具包:
<dependency>
<groupId>com.madgag</groupId>
<artifactId>animated-gif-lib</artifactId>
<version>1.4</version>
</dependency>
好了这样就可以了看下压缩效果
压缩原图:
压缩后的图
更小的图:
好了有什么问题可以留言,如果有帮到你记得点赞哦!