使用gif4j库写一个Java的GUI小程序压缩动态gif图片

    由于微信发图片有大小限制,用Photoshop转换倒是可以做到把图片缩小,但操作起来比较麻烦,所以自己动手用Java写了个小程序,以减少帧数的方式把动态图片压缩,这方法适用于帧数比较多的gif图片。

    在写这个程序之前百度过能完成编辑图片的几个比较有名的Java库,最终使用了Gif4J,感觉这个比较简单,下面是目录结构

使用gif4j库写一个Java的GUI小程序压缩动态gif图片_第1张图片

    因为是即兴之作,所以也命名方式不够严谨,请见谅,源码可以在本人的github上面下载https://github.com/yesqwang/GitEditor.git

    UI及程序入口代码 MainUI.java

package gif.ui;

import gif.function.Edit;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class MainUI extends JFrame implements ActionListener{

	private static final long serialVersionUID = 1L;
	JTextField path;
	JLabel label_path;
	JButton edit;
	JTextArea area;
	JScrollPane pane;
	
	public MainUI() {
		super("GIF图片压缩器");
		init();
	}

	/**
	 * 初始化界面
	 */
	private void init() {
		
		path = new JTextField(20);
		label_path = new JLabel("图片所在文件夹路径:");
		edit = new JButton("开始压缩");
		area = new JTextArea(5, 25);
		
		pane = new JScrollPane(area);
		
		JPanel north = new JPanel(new FlowLayout());
		north.add(label_path);
		north.add(path);
		north.add(edit);
		
		add(north, BorderLayout.NORTH);
		add(pane, BorderLayout.CENTER);
		
		edit.addActionListener(this);
		
		setSize(500, 400);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}
	
	public static void main(String[] args) {
		new MainUI();
	}

	/**
	 * 按钮点击事件
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		//获取文件路径,并作必要的判断
		String p = path.getText();
		File dir = new File(p);
		if(dir.exists()){
			area.setText("开始压缩");
			File[] files = dir.listFiles(new FileFilter() {
				@Override
				public boolean accept(File pathname) {
					return pathname.getName().endsWith(".gif") ? true : false;
				}
			});
			//Edit这个类是自定义的,具体操作可查看这个类的内容
			Edit edit = new Edit();
			//由于该目录下可能有不少待转换的gif图片,所以来了个循环判断
			int failCount = 0;
			for(File f : files){
				//edit(file)这个方法在Edit这个类里,具体操作可查看Edit类
				if(!edit.edit(f)){
					failCount ++;
					area.setText(area.getText() + "\n    GIF图片:" + f.getName() + " 压缩失败!");
				}else{
					area.setText(area.getText() + "\n    GIF图片:" + f.getName() + " 压缩成功,已存入simple目录中!");
				}
				pane.repaint();
			}
			area.setText(area.getText() + "\n 全部操作已完成");
			area.setText(area.getText() + "\n    成功 " + (files.length - failCount) + " 个文件");
			area.setText(area.getText() + "\n    失败 " + failCount + " 个文件");
		}else{
			area.setText("文件路径有误,请重新输入!");
		}
	}
}

图片转换具体代码 Edit.java

package gif.function;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.gif4j.GifDecoder;
import com.gif4j.GifEncoder;
import com.gif4j.GifFrame;
import com.gif4j.GifImage;

public class Edit {
	
	/**
	 * 图片压缩转换
	 * @param file gif图片
	 * @return 转换成功返回true,否则返回false
	 */
	public boolean edit(File file ){
		try {
			long size = file.length();
			GifImage image = GifDecoder.decode(file);//将File重编码转化为GifImage
			int imageFrameNumber = image.getNumberOfFrames();//获取gif图片帧数
			//将图片的每一帧保存入数组中,方便操作
			GifFrame[] frames = new GifFrame[imageFrameNumber];
			for(int i = 0; i < imageFrameNumber; i++){
				frames[i] = image.getFrame(i);
			}
			//设置输出路径及输出文件名:当前目录下新建一个simple文件夹,图片名字不变
			String outPath = file.getParentFile().getPath() + "\\simple";
			String outName = file.getName();
			
			//调用自定义方法转换并保存
			write(frames, size, outPath , outName);
			
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	//减少帧数并延长剩余帧的播放速度
	private void write(GifFrame[] images, long size, String outputDir, String outImageName){
     
        try {
            int imagePageCount = images.length;
            int delay = images[0].getDelay();//获取原图片每一帧的速度
            List imgs = new ArrayList();
            
            double frameSize = size * 1.0 / imagePageCount;//计算平均每一帧的大小
            int count = (int)(1 * 1024 * 1024 / frameSize);//计算每MB大概有多少帧
            int interval = (imagePageCount / count);//计算大概每隔多少帧抽取一帧
            
            System.out.println(imagePageCount + "帧");
            System.out.println(frameSize/1024/1024 + " MB/帧");
            System.out.println(count + "帧/Mb");
            System.out.println("每间隔" + interval + "帧抽取1帧");
            System.out.println("");
            
            //计算转换后的图片每一帧的速度
            delay = (int) (delay * interval);
            //开始转换
            for(int i = 0; i < imagePageCount; i++){
            	if(i == 0 || (interval < i && i % interval == 0)){
            		imgs.add(images[i]);
            	}
            }
           
            //新建一个图片对象,这个对象保存最终输出的图片
            GifImage gifImage = new GifImage();
            gifImage.setLoopNumber(0);
            //给最终输出的图片对象添加转换切割过后的帧
            for (GifFrame f : imgs){
            	f.setDelay(delay);
                gifImage.addGifFrame(f);
            }
            //输出
            File file = new File(outputDir);
            if(!file.exists()){
            	file.mkdirs();
            }
            
            GifEncoder.encode(gifImage, new File(outputDir, outImageName), true);
        } catch (IOException e) {
            e.printStackTrace();
        }
	}
}



https://github.com/yesqwang/GitEditor.gi
https://github.com/yesqwang/GitEditor.git
https://github.com/yesqwang/GitEditor.git

你可能感兴趣的:(小Demo)