引入依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.9</version>
</dependency>
具体代码
public class ImageToVideo {
final static String imagePath = "D:\\video\\images";
final static String videoPath = "D:\\video\\video\\imageVideo666.mp4";
//图片间隔时长
final static int interval = 2;
//视频每秒帧率
final static int frameRate = 30;
//视频宽度
final static int maxWidth = 1260;
//视频高度
final static int maxHeight = 2720;
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(coverImage(image,maxWidth,maxHeight));
}
}
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(saveMp4name, maxWidth, maxHeight, 1);
//视频比特率
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();
}
//图片保持原有长宽比
private static BufferedImage coverImage(BufferedImage originalImage, int targetWidth, int targetHeight){
// 计算新的宽度和高度,保持原始图片的宽高比
int scaledWidth = originalImage.getWidth();
int scaledHeight = originalImage.getHeight();
double aspectRatio = (double) originalImage.getWidth() / originalImage.getHeight();
if (scaledWidth > targetWidth || scaledHeight > targetHeight) {
if (aspectRatio > 1) { // 宽度更大
scaledWidth = targetWidth;
scaledHeight = (int) (scaledWidth / aspectRatio);
} else { // 高度更大或相等
scaledHeight = targetHeight;
scaledWidth = (int) (scaledHeight * aspectRatio);
}
}
// 如果需要,创建一个新的图片并填充背景
BufferedImage newImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g2d = newImage.createGraphics();
g2d.setColor(Color.BLACK); // 设置背景颜色为黑色
g2d.fillRect(0, 0, targetWidth, targetHeight); // 填充整个图片为黑色
// 计算原始图片在新图片上的位置
int x = (targetWidth - scaledWidth) / 2;
int y = (targetHeight - scaledHeight) / 2;
// 将原始图片绘制到新图片上
g2d.drawImage(originalImage, x, y, scaledWidth, scaledHeight, null);
g2d.dispose();
return newImage;
}
}