Java原来可以这么玩!CV实现多张图片生成视频

发布时间:2023年12月25日

前言

比如我像将几张图片变成一个视频的形式发不到短视频平台,虽然短视频平台也有上传图片变成视频的功能,但是我想要具体控制每张图片显示多久后切换到下一个图片,短视频平台目前无法实现,于是乎,我用java代码实现了这个功能。

生成视频展示

多张图片生成视频

javaCV 简介

JavaCV 是一个开源的计算机视觉库,专门为 Java 平台设计。它是一个封装库,通过提供一个统一且易于使用的 API,使得开发者能够访问和利用多种流行的计算机视觉和多媒体处理库。

以下是一些 JavaCV 的主要特性和方面:

  1. 集成多种库:JavaCV 集成了多个开源的计算机视觉和多媒体处理库,包括:

    • OpenCV:一个强大的实时计算机视觉库。
    • FFmpeg:一个广泛用于音频和视频处理的多媒体框架。
  2. 跨平台支持:JavaCV 支持多种操作系统,包括 Windows、Linux、MacOS,以及移动平台 Android 和 iOS。

  3. JNI 调用:JavaCV 基于 JavaCPP 调用方式(JNI 的一层封装),使得 Java 程序能够直接调用 C/C++ 的原生库,从而实现高性能的计算机视觉处理。

  4. 硬件加速:JavaCV 提供了硬件加速的全屏幕图像显示(CanvasFrame),可以提高图像处理和显示的效率。

  5. 并行处理:JavaCV 易于在多个内核中执行并行代码,有助于提升计算密集型任务的性能。

  6. 实用工具类:JavaCV 提供了一系列辅助类和方法,帮助开发者更容易地将 OpenCV、FFmpeg 等库的功能融入到 Java 应用程序中。

  7. 文档与资源:JavaCV 提供了中文文档和中英对照文档下载,包括 API 文档、源代码、Maven 依赖信息文件等,方便开发者参考和学习。

通过使用 JavaCV,开发者可以在 Java 平台上轻松地进行图像处理、视频分析、机器学习等计算机视觉相关的开发工作。

教程

添加jar依赖

   <!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>javacv-platform</artifactId>
			<version>1.5.9</version>
		</dependency>

需要要到的图片如下:
在这里插入图片描述

完整代码如下:


import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author tarzan
 */
public class ImageToVideo {
    final static String imagePath = "E:/images";
    final static String videoPath = "E:/video/imageVideo3.mp4";
    final static int interval = 3;
    //视频每秒帧率
    final static int frameRate = 10;


    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        //图片合成视频
        imagesToVideo(videoPath, imagePath,interval);
        System.out.println("耗时 " + (System.currentTimeMillis() - start) + " ms");
    }

    public static void imagesToVideo(String saveMp4name, String imagesPath,int interval) throws IOException {
        // 列出目录中所有的图片
        File fileDir = new File(imagesPath);
        File[] listFiles = fileDir.listFiles();
        List<BufferedImage> images = new ArrayList<>(listFiles.length);
        for (File file : listFiles) {
            BufferedImage  image= null;
            try {
                //读取原图
                BufferedImage originalImage = ImageIO.read(file);
                if(BufferedImage.TYPE_4BYTE_ABGR==originalImage.getType()){
                    //转换图片类型
                    image = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
                    image.createGraphics().drawImage(originalImage,0,0,null);
                }else {
                    image=originalImage;
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
            if (image != null) {
                images.add(image);
            }
        }
        int maxWidth=Integer.MIN_VALUE;
        int maxHeight=Integer.MIN_VALUE;
        for (BufferedImage image : images) {
            if(image.getWidth()>maxWidth){
                maxWidth=image.getWidth();
            }
            if(image.getHeight()>maxHeight){
                maxHeight=image.getHeight();
            }

        }
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(saveMp4name,1920, 1080, 2);
       // recorder.setVideoBitrate(2000000);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setFormat("mp4");
        recorder.setFrameRate(frameRate);
        recorder.start();
        for (BufferedImage image : images) {
            int i=images.indexOf(image);
            System.out.println("处理进度条: " + (i+1) + "/" + images.size());
            Frame frame = Java2DFrameUtils.toFrame(image);
            for (int j = 0; j < frameRate*interval; j++) {
                recorder.record(frame);
            }
            i++;
        }
        recorder.stop();
        recorder.release();
    }

}
  • 根据自己的情况修改代码中的图片目录和生成视频的路径,以及每张图片显示的时长。

原理

通过遍历指定文件夹下的所有图片,求出最大的宽度和高度,设置为视频的宽高。以每秒30帧为单位,复制每张图片为30张或者30*n张,添加到视频录制器内,最终生成视频。

控制台运行输出日志
在这里插入图片描述

  • 6张图片生成每秒30帧的视频,需要8.5s。
  • 6张图片生成每秒10帧的视频,需要4.6s。
  • 帧率设置为10以下时候,首次打开视频的开头会出现延时黑屏的现象,所以建议帧率为10以上。
    在这里插入图片描述
    -后续还可以用视频工具(比如剪映等)整合背景音乐视频。
文章来源:https://blog.csdn.net/weixin_40986713/article/details/135208878
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。