java视频生成缩略图_Java——使用javacv生成视频缩略图

本文介绍了如何使用Java结合javacv库生成视频缩略图。通过添加依赖,设置视频路径,利用FFmpegFrameGrabber获取视频帧,然后进行图像处理和保存,实现视频缩略图的生成。提供了两种方式,一种是获取视频中间帧,另一种是随机生成多张缩略图。
摘要由CSDN通过智能技术生成

转载大佬文章,以备后期再次需要,亲测使用有效

添加依赖

在pom.xml中添加依赖配置

org.bytedeco

javacv-platform

1.3.1

1、获取视频中间的帧作为缩略图,并返回缩略图实际存放地址

package com.lyz.medis.image;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import javax.imageio.ImageIO;

import org.bytedeco.javacpp.opencv_core;

import org.bytedeco.javacpp.opencv_core.IplImage;

import org.bytedeco.javacv.FFmpegFrameGrabber;

import org.bytedeco.javacv.Frame;

import org.bytedeco.javacv.FrameGrabber.Exception;

import org.bytedeco.javacv.Java2DFrameConverter;

import org.bytedeco.javacv.OpenCVFrameConverter;

/**

* 获取视频缩略图

* @author liuyazhuang

*

*/

public class VideoImage {

private static final String IMAGEMAT = "png";

private static final String ROTATE = "rotate";

/**

* 默认截取视频的中间帧为封面

*/

public static final int MOD = 2;

public static void main(String[] args) throws Exception {

System.out.println(randomGrabberFFmpegImage("C:/lyz/1522372294724_79583.mov", 2));

}

/**

* 获取视频缩略图

* @param filePath:视频路径

* @param mod:视频长度/mod获取第几帧

* @throws Exception

*/

public static String randomGrabberFFmpegImage(String filePath, int mod) throws Exception {

String targetFilePath = "";

FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);

ff.start();

String rotate = ff.getVideoMetadata(ROTATE);

int ffLength = ff.getLengthInFrames();

Frame f;

int i = 0;

int index = ffLength / mod;

while (i < ffLength) {

f = ff.grabImage();

if(i == index){

if (null != rotate && rotate.length() > 1) {

OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();

IplImage src = converter.convert(f);

f = converter.convert(rotate(src, Integer.valueOf(rotate)));

}

targetFilePath = getImagePath(filePath, i);

doExecuteFrame(f, targetFilePath);

break;

}

i++;

}

ff.stop();

return targetFilePath;

}

/**

* 根据视频路径生成缩略图存放路径

* @param filePath:视频路径

* @param index:第几帧

* @return:缩略图的存放路径

*/

private static String getImagePath(String filePath, int index){

if(filePath.contains(".") && filePath.lastIndexOf(".") < filePath.length() - 1){

filePath = filePath.substring(0, filePath.lastIndexOf(".")).concat("_").concat(String.valueOf(index)).concat(".").concat(IMAGEMAT);

}

return filePath;

}

/**

* 旋转图片

* @param src

* @param angle

* @return

*/

public static IplImage rotate(IplImage src, int angle) {

IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());

opencv_core.cvTranspose(src, img);

opencv_core.cvFlip(img, img, angle);

return img;

}

/**

* 截取缩略图

* @param f

* @param targerFilePath:封面图片

*/

public static void doExecuteFrame(Frame f, String targerFilePath) {

if (null == f || null == f.image) {

return;

}

Java2DFrameConverter converter = new Java2DFrameConverter();

BufferedImage bi = converter.getBufferedImage(f);

File output = new File(targerFilePath);

try {

ImageIO.write(bi, IMAGEMAT, output);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 根据视频长度随机生成随机数集合

* @param baseNum:基础数字,此处为视频长度

* @param length:随机数集合长度

* @return:随机数集合

*/

public static List random(int baseNum, int length) {

List list = new ArrayList(length);

while (list.size() < length) {

Integer next = (int) (Math.random() * baseNum);

if (list.contains(next)) {

continue;

}

list.add(next);

}

Collections.sort(list);

return list;

}

}

2、随机生成多张缩略图,不返回缩略图实际存放地址

package com.lyz.medis.image;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

import javax.imageio.ImageIO;

import org.bytedeco.javacpp.opencv_core;

import org.bytedeco.javacpp.opencv_core.IplImage;

import org.bytedeco.javacv.FFmpegFrameGrabber;

import org.bytedeco.javacv.Frame;

import org.bytedeco.javacv.FrameGrabber.Exception;

import org.bytedeco.javacv.Java2DFrameConverter;

import org.bytedeco.javacv.OpenCVFrameConverter;

/**

* 获取图片缩略图

* @author liuyazhuang

*

*/

public abstract class VideoImageFrame {

public static void main(String[] args) throws Exception {

randomGrabberFFmpegImage("e:/lyz/ffmpeg.mp4", "./target", "screenshot", 5);

}

/**

* 生成图片缩略图

* @param filePath:视频完整路径

* @param targerFilePath:缩略图存放目录

* @param targetFileName:缩略图文件名称

* @param randomSize:生成随机数的数量

* @throws Exception

*/

public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName, int randomSize) throws Exception {

FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);

ff.start();

String rotate = ff.getVideoMetadata("rotate");

int ffLength = ff.getLengthInFrames();

List randomGrab = random(ffLength, randomSize);

int maxRandomGrab = randomGrab.get(randomGrab.size() - 1);

Frame f;

int i = 0;

while (i < ffLength) {

f = ff.grabImage();

if (randomGrab.contains(i)) {

if (null != rotate && rotate.length() > 1) {

OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();

IplImage src = converter.convert(f);

f = converter.convert(rotate(src, Integer.valueOf(rotate)));

}

doExecuteFrame(f, targerFilePath, targetFileName, i);

}

if (i >= maxRandomGrab) {

break;

}

i++;

}

ff.stop();

}

/**

* 旋转图片

* @param src:图片

* @param angle:旋转角度

* @return

*/

public static IplImage rotate(IplImage src, int angle) {

IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());

opencv_core.cvTranspose(src, img);

opencv_core.cvFlip(img, img, angle);

return img;

}

/**

* 生成缩略图

* @param f Frame对象

* @param targerFilePath

* @param targetFileName

* @param index

*/

public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName, int index) {

if (null == f || null == f.image) {

return;

}

Java2DFrameConverter converter = new Java2DFrameConverter();

String imageMat = "png";

String FileName = targerFilePath + File.separator + targetFileName + "_" + index + "." + imageMat;

BufferedImage bi = converter.getBufferedImage(f);

File output = new File(FileName);

try {

ImageIO.write(bi, imageMat, output);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 随机生成随机数集合

* @param baseNum:随机种子

* @param length:随机数集合长度

* @return:随机数集合

*/

public static List random(int baseNum, int length) {

List list = new ArrayList<>(length);

while (list.size() < length) {

Integer next = (int) (Math.random() * baseNum);

if (list.contains(next)) {

continue;

}

list.add(next);

}

Collections.sort(list);

return list;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值