使用JavaCV把图片合成视频(实用)

用JavaCV把图片合成视频

这是我最近在做的一个小需求 就是后台把多张照片生成一个视频 并且展示到前端。

一般处理图片视频有两种方式 第一种使用OpenCV 底层c开发的,效率非常快,c和python都会使用这款插件。但是Java中使用也可以 只不过要去官网下载jar 并且依赖dll文件 才可以正常使用。在Linux中更难受 所以在Java中不推荐使用OpenCV。

我们这次主要说第二种 使用JavaCV来处理这个需求,其实他也是封装了opencv ,只不过加了java中的一些接口…废话不过说。

首先我们得导入Javacv的依赖
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.5.2</version>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.2</version>
</dependency>
首先把要生成视频的图片地址放到一个map中 因为我图片存在本地所以 做了一些逻辑
//将一个gis中的一个文件夹 转map集合
public static Map<Integer,File> gisFileToMap(String filePath, GisCondition gisCondition){
    long startTime = System.currentTimeMillis();
    //根据类型选择文件路径
    String path = filePath+File.separator+typeNames[gisCondition.getTypeId()];
    Map<Integer, File> imgMap = new HashMap<Integer, File>();
    Integer index = 0;
    try {
        File file = new File(path);
        for (File listFile : file.listFiles()) {
            log.info("子文件路径==>"+listFile);
            Gis gis = appendGis(listFile);
            //提前跳出筛选
            log.info("start1===>"+gis.getRecordTime().getTime());
            log.info("start2===>"+gisCondition.getStartDate().getTime());
            if (gis.getRecordTime().getTime()>gisCondition.getEndDate().getTime()) break;
            if (gis.getRecordTime().getTime() < gisCondition.getStartDate().getTime()) continue;
            //根据开始日期和结束日期选择图片
            if (gis.getRecordTime().getTime() >=
                    gisCondition.getStartDate().getTime() &&
                    gis.getRecordTime().getTime() <=
                            gisCondition.getEndDate().getTime())
            {
                imgMap.put(index,listFile);
                index++;
            }
        }
    }catch (Exception e){
        log.info("解析gis图片失败:{}",e.getMessage());
    }
    System.out.println("筛选图片耗时===》"+(System.currentTimeMillis() - startTime));
    return imgMap;
}
然后通过tomcat 映射本地路径 返回最终的一个展示路径
@Override
public String getGisListByLocalFile2(GisCondition gisCondition) {
    //把原有的视频删除
    File file = new File(localPath);
    if (file.exists()){
        for (File listFile : file.listFiles()) {
            listFile.delete();
        }
    }
    //根据条件筛选出图片
    Map<Integer, File> imgMap = CommonUtil.gisFileToMap(filePath, gisCondition);
    log.info("==》照片总数:{}",imgMap.size());
    String uuid = UUID.randomUUID().toString();
    localPath =  localPath+uuid+".mp4";
    tomcatPath = tomcatPath+uuid+".mp4";
    try {
        PicToAviUtil.createMp4(localPath,imgMap,width,height);
    } catch (FrameRecorder.Exception e) {
        log.info("生成视频出错:{}",e.getMessage());
    }
    return tomcatPath;
}
然后使用的该工具类
package com.gis.util;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Map;
/**
 * 图片与视频转换工具类
 */
public class PicToAviUtil {
    //设置每秒的帧数
    private static final Integer FRAME = 3;
    //设置一秒钟几幅图像
    private static final Integer SECOND_IMG = 2;
    /**
     * @param localPath 保存到本地的路径
     * @param imgMap  需要转视频的 图片
     * @param width 宽度
     * @param height  高度
     * @throws FrameRecorder.Exception
     */
    public static void createMp4(String localPath, Map<Integer, File> imgMap,
                                  int width, int height) throws FrameRecorder.Exception {
        long startTime = System.currentTimeMillis();
        //视频宽高最好是按照常见的视频的宽高  16:9  或者 9:16
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(localPath, width, height);
        //设置视频编码层模式
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //设置视频多少帧每秒
        recorder.setFrameRate(FRAME);
        //设置视频图像数据格式
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        //视频格式  可以自己选
        recorder.setFormat("mp4");
        try {
            recorder.start();
            Java2DFrameConverter converter = new Java2DFrameConverter();
            //录制一个自定义视频
            Integer index = 0;
            for (; index < imgMap.size(); index++) {
                BufferedImage read = ImageIO.read(imgMap.get(index));
                //根据帧数  记录每一帧都是一样的
                for (int j = 0; j < FRAME; j++) {
                    recorder.record(converter.getFrame(read));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //最后一定要结束并释放资源
            recorder.stop();
            recorder.release();
        }
        System.out.println("生成视频结束==>"+(System.currentTimeMillis()-startTime));
    }
}
最后到页面上可以展示视频

在这里插入图片描述

然后可以根据自己的需求去改变工具类中的方法。
最后到页面上可以展示视频
然后可以根据自己的需求去改变工具类中的方法。
JavaCV 不仅可以图片合成视频 还可以对视频进行抽帧 做人脸识别 身份认证等等…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值