JavaCV图片和视频互转 视频添加文字

文章目录

  • 前言
  • 一、视频分解为帧图片
  • 二、图片 转视频
  • 三、视频添加文字
  • 总结


前言

JavaCV处理BGR通道上文介绍了如何简单处理图片BGR以及灰度,这期我们来介绍如何使用JavaCV分解视频、合成视频。。


提示:以下是本篇文章正文内容,下面案例可供参考

一、视频分解为帧图片

示例:使用JavaCV包下的FFmpegFrameGrabber读取视频帧

package com.example.demo;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.opencv_core.Mat;
import org.junit.Test;

import java.io.File;

public class VideoTest {
    @Test
    public void readVideoFrame(){
        File file = new File("D:\\vodeiPredit\\20210528135144\\1001.mp4");
        try (FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(file); OpenCVFrameConverter.ToOrgOpenCvCoreMat cvCoreMat = new OpenCVFrameConverter.ToOrgOpenCvCoreMat()){
            fFmpegFrameGrabber.start();
            Frame frame = null;
            int frameNum = 0;
            //读取每帧视频
            while ((frame = fFmpegFrameGrabber.grabImage()) != null) {
                Mat mat = cvCoreMat.convertToMat(frame);
                //保存图片
                opencv_imgcodecs.imwrite("Frame"+frameNum+".jpg",mat);
                frameNum++;
            }
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
    }
}

以上便是读取视频 并将视频转为图片保存的代码,需要注意 FFmpegFrameGrabber satrt()之后才能读取到帧图片 FFmpegFrameGrabber、OpenCVFrameConverter.ToOrgOpenCvCoreMat 使用过后需要close() 此处使用 try with形式关闭。

二、图片 转视频

package com.example.demo;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.opencv_core.Mat;
import org.junit.Test;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.Duration;
import java.time.LocalDateTime;
public class VideoTest {
 

    @Test
    public void img2Video(){
        try (OpenCVFrameConverter.ToOrgOpenCvCoreMat cvCoreMat = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:/Code/IdeaCode/demo/image/2001.mp4", 1280, 720);){
            // 视频相关配置
            //设置帧率  帧率和解码器 可以去原视频获取 否则 可能会报错
            recorder.setFrameRate(25);
            //设置视频解码器
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.start();
            for (int i = 0; i < 116; i++) {
                String path = "D:/Code/IdeaCode/demo/image/Frame"+i+".jpg";
                File file = new File(path);
                if (!file.exists()) {
                    continue;
                }
                //读图片为Mat
                Mat mat = opencv_imgcodecs.imread(path);
                //Mat转Frame
                Frame convert = cvCoreMat.convert(mat);
                recorder.record(convert);
            }
            recorder.stop();
            recorder.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

注意最后释放record资源 否则在web项目中可能会出现问题

三、视频添加文字

package com.example.demo;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Scalar;

import java.io.File;

/**
 * @Author hexin210426
 * @Description
 * @Date 2021/8/20
 **/
@Slf4j
public class VideoDemo {

    public static void main(String[] args) {
        //读取文件
        File file = new File("D:\\vodeiPredit\\20210528135144\\1001.mp4");
        //ffmpeg 读取视频

        FFmpegFrameRecorder recorder = null;
        //转换Frame、Mat
        try (FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(file); OpenCVFrameConverter.ToOrgOpenCvCoreMat cvCoreMat = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();){
            fFmpegFrameGrabber.start();
            Frame frame = null;
            //创建视频Record 使用它来合成视频
            recorder = getfFmpegFrameRecorder(fFmpegFrameGrabber);
            recorder.start();
            //读取视频每一帧图片
            int num = 0;
            Scalar scalar = new Scalar();
            scalar.green(0);
            scalar.blue(0);
            scalar.red(255);
            //处理图片  添加文字
            while ((frame = fFmpegFrameGrabber.grabImage()) != null) {

                //转为JavaCV的Mat 可以使用convertToOrgOpenCvCoreMat或convert 转为OpenCV的Mat
                Mat mat = cvCoreMat.convertToMat(frame);
                //Mat添加文字
                opencv_imgproc.putText(mat, "num is "+ num, new Point(100, 100), opencv_imgproc.FONT_HERSHEY_SIMPLEX, 1.0, scalar, 1, opencv_imgproc.LINE_AA,false);
                //Mat转Frame
                Frame convert = cvCoreMat.convert(mat);
                //使用ffmpeg记录当前帧
                recorder.record(convert);
                num++;
            }
        } catch (FFmpegFrameRecorder.Exception | FrameGrabber.Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (recorder != null){
                    recorder.stop();
                    recorder.release();
                    recorder.close();
                }
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
            }
        }


    }

    public static FFmpegFrameRecorder getfFmpegFrameRecorder( FFmpegFrameGrabber fFmpegFrameGrabber) {
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:\\vodeiPredit\\20210528135144\\1002.mp4", fFmpegFrameGrabber.getImageWidth(), fFmpegFrameGrabber.getImageHeight(), fFmpegFrameGrabber.getAudioChannels());
        // 视频相关配置,取原视频配置
        recorder.setFrameRate(fFmpegFrameGrabber.getFrameRate());
        recorder.setVideoCodec(fFmpegFrameGrabber.getVideoCodec());
        recorder.setVideoBitrate(fFmpegFrameGrabber.getVideoBitrate());

        // 音频相关配置,取原音频配置
        recorder.setSampleRate(fFmpegFrameGrabber.getSampleRate());
        recorder.setAudioCodec(fFmpegFrameGrabber.getAudioCodec());
        recorder.setAudioBitrate(fFmpegFrameGrabber.getAudioBitrate());
        return recorder;
    }
}


总结

以上是JavaCV部分处理视频的方式,仅为个人理解,不代表完全正确,有不同见解可以提出,一起学习!

你可能感兴趣的:(java,opencv)