Java小项目 屏幕自定义尺寸GIF生成器V1.0

鉴于最近需要合成一些GIF图像,而看到很多GIF制作都需要收费,所以花了些时间,能基本满足自己的需求了,读者可以随意自行复制修改。




效果(这里的图片本来可以达到是14M效果好,但是超过了csdn上传图片文件的大小限制,所以保持了缩放,图片帧也会有点少,只有4.7M,画面有会有点断断续续的,读者可以自己修改一些代码中有关FPS的参数,就会达到流畅的效果… )

在这里插入图片描述

相关代码如下:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.wu</groupId>
    <artifactId>Edge</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.madgag</groupId>
            <artifactId>animated-gif-lib</artifactId>
            <version>1.4</version>
        </dependency>
    </dependencies>
</project>

GIF.java

package com.wu;

import com.madgag.gif.fmsware.AnimatedGifEncoder;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

public class GIF extends JFrame {
    private Robot robot = null;
    private int times = 2; // 初始命中次数
    private Rectangle rectangle = new Rectangle();
    private BufferedImage[] images = null;
    private int frames = 0; // 当前帧数
    private final static int FRAMES = 150; // 最大帧数 只影响总帧数
    private int framePerMS = 100; // 毫秒每帧 只影响帧捕捉时间间隔
    private int currentProgress = 0; // 当前进度
    private String path = null; // 文件路径
    private FileOutputStream fileOutputStream = null; // 导出文件流
    private final static String GIFNAME = "MyGif.gif"; // 默认文件名

    private JTextField text = null;

    public GIF(){
        this.setSize(350,110);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("GIF生成");
        this.setLayout(null);
        this.images = new BufferedImage[FRAMES];
        this.setAlwaysOnTop(true);

        this.addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent e){
                // System.out.println("这里工作了… ");
                if(e.getKeyChar() == 's' && times > 0){
                    times--;
                    Point point  = MouseInfo.getPointerInfo().getLocation(); // 获取当前鼠标坐标
                    if(times == 1){
                        rectangle.x = point.x;
                        rectangle.y = point.y;
                    }else if(times == 0){
                        if(point.x > rectangle.x && point.y < rectangle.y){ // 相对与第一个点的第一坐标系内
                            rectangle.height = rectangle.y - point.y;
                            rectangle.y = point.y;
                            rectangle.width = point.x - rectangle.x;

                        }else if(point.x < rectangle.x && point.y < rectangle.y){ // 相对于第一个点的第二坐标系
                            int temp = point.x;
                            point.x = rectangle.x;
                            rectangle.x = temp;
                            temp = point.y;
                            point.y = rectangle.y;
                            rectangle.y = temp;

                            rectangle.width = point.x - rectangle.x;
                            rectangle.height = point.y - rectangle.y;
                        }else if(point.x < rectangle.x && point.y > rectangle.y){ // 相对于第一个点的第三坐标系
                            rectangle.width = rectangle.x - point.x;
                            rectangle.height = point.y - rectangle.y;
                            rectangle.x = point.x;
                        }else{ // 相对于第一个点的第四坐标系
                            rectangle.width = point.x - rectangle.x;
                            rectangle.height = point.y - rectangle.y;
                        }
                    }

                }

            }
        });
        this.setResizable(false);
        try{
            Thread.sleep(100);
            robot = new Robot();
        }catch(Exception exception){}


        JLabel fileName = null;
        {
            fileName = new JLabel("导出位置:");
            this.add(fileName);
            fileName.setBounds(5,10,83,30);
            final Font font = new Font("宋体",Font.BOLD,17);
            fileName.setFont(font);
            text = new JTextField("\\");
            this.add(text);
            text.setToolTipText("GIF文件导出位置");
            text.setEditable(false); // 初始设置为不可编辑状态
            text.setForeground(Color.gray);
            text.setBackground(Color.white);
            text.setFont(font);
            text.setBounds(92,10,242,30);
            {
                text.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseExited(MouseEvent e) {
                        // System.out.println("鼠标退出… ");
                        text.setFocusable(false);
                        text.setEditable(false);

                        try{ // 处理文件位置异常问题
                            path = text.getText();
                            File file = new File(path);
                            if(path.charAt(path.length() - 1) == '\\'){
                                fileOutputStream = new FileOutputStream(file+GIFNAME);
                            }else{
                                fileOutputStream = new FileOutputStream(file+"\\"+GIFNAME);
                            }
                        }catch(Exception exception){
                            JOptionPane jOptionPane = new JOptionPane();
                            JLabel jLabel = new JLabel("导出文件目录错误,并重置矩形区域!");
                            jLabel.setFont(font);/**
                            Component[] components = jOptionPane.getComponents();
                            JPanel jPanel = (JPanel) components[1];
                            JButton jButton = (JButton) jPanel.getComponent(0);
                            jButton.setFont(font);
                            jButton.setBorderPainted(false);
                            jButton.setBorder(BorderFactory.createRaisedBevelBorder());
                            **/
                            jOptionPane.showMessageDialog(null,jLabel,"Error",JOptionPane.WARNING_MESSAGE);
                            times = 2; // 还原
                            text.setText("\\");
                        }
                    }
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        // System.out.println("鼠标点击… ");
                        text.setEditable(true); // 设置为可编辑状态
                        text.setFocusable(true);
                    }


                });
            }
        }
        int delay = framePerMS; // 监听
        final JProgressBar progressBar = new JProgressBar();
        // 设置进度的 最小值 和 最大值
        progressBar.setMinimum(0);
        progressBar.setMaximum(100);
        // 设置当前进度值
        progressBar.setValue(currentProgress);
        // 绘制百分比文本(进度条中间显示的百分数)
        progressBar.setStringPainted(true);
        progressBar.setBounds(20,50,300,20);
        this.add(progressBar);
        this.setVisible(true);

        ActionListener actionListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(rectangle.x >= 0 && rectangle.y >= 0 && rectangle.width > 0 && rectangle.height > 0 &&
                frames < FRAMES){
                    try{
                        images[frames++] = robot.createScreenCapture(rectangle);
                        // ImageIO.write(image,"jpg",new File("C:\\Users\\Administrator\\OneDrive\\图片\\1.jpg"));
                        progressBar.setValue(frames*100/FRAMES);
                    }catch(Exception exception){
                        exception.printStackTrace();
                    }
                }else if(frames >= FRAMES){
                    try{
                        generateGIF();
                    }catch(Exception exception){
                        System.exit(0);
                    }
                }
            }
        };
        // 启动计时器
        new Timer(delay,actionListener).start();

    }

    /**
     * 生成GIF
     */
    public void generateGIF() throws Exception{
        AnimatedGifEncoder animatedGifEncoder = new AnimatedGifEncoder();
        try{
            animatedGifEncoder.start(fileOutputStream);
            animatedGifEncoder.setDelay(framePerMS);
            animatedGifEncoder.setRepeat(0);
            for(int i = 0 ; i < FRAMES ; i++){
                animatedGifEncoder.addFrame(images[i]);
            }
            animatedGifEncoder.finish();
            System.exit(0); // 退出

        }catch(Exception e){
            throw e;
        }
    }
    public static void main(String[] args) throws Exception{
        new GIF();
    }
}
功能说明:第一次点击's'键确定一个矩形GIF图片角,再次点击's'键确定另一个图片角,然后开始根据该矩形区域截取视频帧,最终等待一会,并把合成的GIF图片保存到自定义目录下,默认文件名为MyGif.gif。

读者有疑问欢迎留言…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值