比如我像将几张图片变成一个视频的形式发不到短视频平台,虽然短视频平台也有上传图片变成视频的功能,但是我想要具体控制每张图片显示多久后切换到下一个图片,短视频平台目前无法实现,于是乎,我用java代码实现了这个功能。
生成视频展示
多张图片生成视频
JavaCV 是一个开源的计算机视觉库,专门为 Java 平台设计。它是一个封装库,通过提供一个统一且易于使用的 API,使得开发者能够访问和利用多种流行的计算机视觉和多媒体处理库。
以下是一些 JavaCV 的主要特性和方面:
集成多种库:JavaCV 集成了多个开源的计算机视觉和多媒体处理库,包括:
跨平台支持:JavaCV 支持多种操作系统,包括 Windows、Linux、MacOS,以及移动平台 Android 和 iOS。
JNI 调用:JavaCV 基于 JavaCPP 调用方式(JNI 的一层封装),使得 Java 程序能够直接调用 C/C++ 的原生库,从而实现高性能的计算机视觉处理。
硬件加速:JavaCV 提供了硬件加速的全屏幕图像显示(CanvasFrame),可以提高图像处理和显示的效率。
并行处理:JavaCV 易于在多个内核中执行并行代码,有助于提升计算密集型任务的性能。
实用工具类:JavaCV 提供了一系列辅助类和方法,帮助开发者更容易地将 OpenCV、FFmpeg 等库的功能融入到 Java 应用程序中。
文档与资源: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张,添加到视频录制器内,最终生成视频。
控制台运行输出日志