使用javacv导出视频帧图片

maven导入依赖包:

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
            <version>3.4.1-1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>

java方法:

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;

/**
 * 视频工具
 * @author
 *
 */
public class VideoUtil {
    /**
     * 获取指定视频的帧并保存为图片至指定目录
     * @param file  源视频文件
     * @param framefile  截取帧的图片存放路径
     * @throws Exception
     */
    public static void fetchPic(File file, String framefile,int second) throws Exception{
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
        ff.start();
        int lenght = ff.getLengthInAudioFrames();
        System.out.println(ff.getFrameRate());

        int i = 0;
        Frame frame = null;
        second = 0;
        while (i < lenght) {
            // 过滤前5帧,避免出现全黑的图片,依自己情况而定
            frame = ff.grabImage();
//            if (i>=(int) (ff.getFrameRate()*second)&&frame.image != null) {
            System.out.print(i+",");
            if(i==50){
                int a =1;
            }
            if(frame!=null&&frame.image!=null) {
                System.out.println(i);
                writeToFile(frame, i);
            }
//                second++;
//            }
            i++;
        }
        ff.stop();
    }

    public static void writeToFile(Frame frame,int second){
        File targetFile = new File("E:/223/"+second+".jpg");
        String imgSuffix = "jpg";

        Java2DFrameConverter converter =new Java2DFrameConverter();
        BufferedImage srcBi =converter.getBufferedImage(frame);
        int owidth = srcBi.getWidth();
        int oheight = srcBi.getHeight();
        // 对截取的帧进行等比例缩放
        int width = 800;
        int height = (int) (((double) width / owidth) * oheight);
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);
        try {
            ImageIO.write(bi, imgSuffix, targetFile);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取视频时长,单位为秒
     * @param file
     * @return 时长(s)
     */
    public static Long getVideoTime(File file){
        Long times = 0L;
        try {
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
            ff.start();
            times = ff.getLengthInTime()/(1000*1000);
            ff.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return times;
    }

//    public void getBySecond() {
//        opencv_videoio.CvCapture capture = opencv_highgui.cvC("D:/085402.crf");
//
//
//
//        //帧率
//        int fps = (int) opencv_highgui.cvGetCaptureProperty(capture, opencv_highgui.CV_CAP_PROP_FPS);
//        System.out.println("帧率:"+fps);
//
//        opencv_core.IplImage frame = null;
//        double pos1 = 0;
//
//        int rootCount = 0;
//
//        while (true) {
//
//            //读取关键帧
//            frame = opencv_highgui.cvQueryFrame(capture);
//
//            rootCount = fps;
//            while(rootCount > 0 ){
//                //这一段的目的是跳过每一秒钟的帧数,也就是说fps是帧率(一秒钟有多少帧),在读取一帧后,跳过fps数量的帧就相当于跳过了1秒钟。
//                frame = opencv_highgui.cvQueryFrame(capture);
//                rootCount--;
//            }
//
//            //获取当前帧的位置
//            pos1 = opencv_highgui.cvGetCaptureProperty(capture,opencv_highgui.CV_CAP_PROP_POS_FRAMES);
//            System.out.println(pos1);
//
//            if (null == frame)
//                break;
//
//            opencv_highgui.cvSaveImage("d:/img/" + pos1 + ".jpg",frame);
//
//        }
//
//        opencv_highgui.cvReleaseCapture(capture);
//    }

    public static void main(String[] args){
        try {
            File file = new File("E:/22.mp4");
            VideoUtil.fetchPic(file,"E:/123.jpg",5);
            System.out.println(VideoUtil.getVideoTime(file));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用JavaCV库中的FFmpegFrameGrabber和FFmpegFrameRecorder类实现在视频中添加图片水印。具体实现步骤如下: 1. 使用FFmpegFrameGrabber类打开视频文件。 2. 使用CanvasFrame类在视频帧上绘制图片水印。 3. 使用FFmpegFrameRecorder类保存带水印的视频。 这里有一个简单的样例: ``` public static void main(String[] args) throws Exception { String videoFile = "original.mp4"; String watermarkedVideoFile = "watermarked.mp4"; FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoFile); frameGrabber.start(); Frame frame; CanvasFrame canvasFrame = new CanvasFrame("Watermarked Video"); canvasFrame.setCanvasSize(frameGrabber.getImageWidth(), frameGrabber.getImageHeight()); while (canvasFrame.isVisible() && (frame = frameGrabber.grab()) != null) { BufferedImage image = frame.getBufferedImage(); Graphics graphics = image.getGraphics(); BufferedImage watermark = ImageIO.read(new File("watermark.png")); graphics.drawImage(watermark, 0, 0, null); canvasFrame.showImage(image); } canvasFrame.dispose(); FFmpegFrameRecorder frameRecorder = new FFmpegFrameRecorder(watermarkedVideoFile, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels()); frameRecorder.start(); frameGrabber.restart(); while ((frame = frameGrabber.grab()) != null) { frameRecorder.record(frame); } frameRecorder.stop(); frameGrabber.stop(); } ``` 请注意,上面这份代码只是一个示例,如果要用在生产中,更多的错误处理需要加入。 需要先安装 FFmpeg 和 OpenCV 的库,JavaCV包含了它们

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值