Java 截取视频资料中的某一帧作为缩略图

 更新时间:2021年09月16日 09:31:42   作者:小小张自由—>张有博  
最近项目中有一个需求,就是Java 截取视频资料中的某一帧作为缩略图,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最近项目中有一个需求,就是要实现视频资料的收藏功能,当时想了想,收藏记录实现并不是很难,但是想展现出视频的缩略图,就要想想其他办法了,所以就想到了截取视频资料中的某一帧作为缩略图,我没有选择截取第一帧,选择的是第五帧,因为第一帧可能没有内容。

基础知识

JavaCV:功能很强大,封装了很多很视频、图片相关的内容。

JavaCV 是一款基于JavaCPP

调用方式(JNI的一层封装),由多种开源计算机视觉库组成的包装库,封装了包含FFmpeg、OpenCV、tensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。

JavaCV基于Apache License Version 2.0协议和GPLv2两种协议 ,

JavaCV支持Windows、Linux、MacOS,Android、IOS在内的Java平台上调用这些接口。

FFmpegFrameGrabber

FFmpegFrameGrabber可以理解为解码器,也可以理解为帧收集器,可以获取视频资料的各种详细信息,时长,宽高,帧等,很强大。

BufferedImage,ImageIO

BufferedImage类是Image的一个子类,是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中。

ImageIO提供read()和write()静态方法,读写照片

将图片加载到内存中

 //需要是一个本地文件
 String imgPath = "‪C:\Users\Administrator\Videos\999.jpg";  
 BufferedImage image = ImageIO.read(new FileInputStream(imgPath));

 将内存中的图片写到本地

BufferedImage bi=~某个值
File outputfile  = new File("save.png");
//参数 
// bi:要写入的RenderedImage 
// png:格式类型
// outputfile:要写入的OutputStream 
ImageIO.write(bi,"png",outputfile);

MultipartFile

MultipartFile在上一篇文章中介绍过了。

Java文件上传实例并解决跨域问题

具体实现

引入依赖

本功能使用的Jar包是javacv,javacv-platform。因为这个包有150多M,很多依赖项都用不到,所以,将不需要的移除取出。

<!--start:视频获取某一帧的图片-->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.4.4</version>
    <exclusions>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>flycapture</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libdc1394</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libfreenect</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libfreenect2</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>librealsense</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>videoinput</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>tesseract</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>leptonica</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>flandmark</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>artoolkitplus</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.4.4</version>
    <exclusions>
        <exclusion>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>flycapture-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libdc1394-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libfreenect-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>libfreenect2-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>librealsense-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>videoinput-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>tesseract-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>leptonica-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>flandmark-platform</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>artoolkitplus-platform</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--end:视频获取某一帧的图片-->

Java代码

/**
 * 将视频文件帧处理并以“jpg”格式进行存储。
 * 依赖FrameToBufferedImage方法:将frame转换为bufferedImage对象
 * 参数可串本地文件,或者网络文件
 * @param videoFileName http://d-godone.dmsd.tech/goDone/M00/00/0A/wKg8O2D2mnqEMg7wAAAAALbl5Ys275.mp4
 */
public  String videoFramer(String videoFileName){
    //最后获取到的视频的图片的路径
    String videPicture="";
    //Frame对象
    Frame frame = null;
    //标识
    int flag = 0;
    try {
         /*
        获取视频文件
        */
        FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber( videoFileName);
        log.info("开始截取视频:");
//            av_register_all();//解决报错 avformat_open_input() error -138: Could not open input
//            avcodec_register_all();
//          当视频打不开时,会报错
        fFmpegFrameGrabber.start();
        //获取视频总帧数
        int ftp = fFmpegFrameGrabber.getLengthInFrames();
        log.info("时长 " + ftp / fFmpegFrameGrabber.getFrameRate() / 60);
 
        while (flag <= ftp) {
            //获得每一帧
            frame = fFmpegFrameGrabber.grabImage();
            /*
            对视频的第五帧进行处理
             */
            if (frame != null && flag==5) {
 
               //将文件转换
                BufferedImage bufferedImage = FrameToBufferedImage(frame);
                //将bufferedImage转换成MultipartFile--方便文件上传
                MultipartFile multipartFile = fileCase(bufferedImage);
                log.info("开始文件上传:");
                //文件上传--上传到FastDFS中,并返回URL
                String fileLoad = fileLoad(multipartFile);
 
                videPicture=fileLoad;
                log.info("文件上传成功{}",fileLoad);
                break;
            }
            flag++;
        }
        fFmpegFrameGrabber.stop();
        fFmpegFrameGrabber.close();
    } catch (Exception E) {
        E.printStackTrace();
    }
    return videPicture;
}

两个文件类型转换的方法Frame->BufferedImage->MultipartFile

/**
 * 文件转换,将Frame转换成BufferedImage
 * @param frame Frame
 * @return
 */
public static BufferedImage FrameToBufferedImage(Frame frame) {
    //创建BufferedImage对象
    Java2DFrameConverter converter = new Java2DFrameConverter();
    BufferedImage bufferedImage = converter.getBufferedImage(frame);
    return bufferedImage;
}
 
 
/**
 * 文件转换将BufferedImage转换成MultipartFile:为了文件上传
 * @param image
 * @return
 */
public static MultipartFile fileCase(BufferedImage image){
    //得到BufferedImage对象
   // BufferedImage bufferedImage = JoinTwoImage.testEncode(200, 200, url);
    MultipartFile multipartFile= null;
    try {
        //创建一个ByteArrayOutputStream
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        //把BufferedImage写入ByteArrayOutputStream
        ImageIO.write(image, "jpg", os);
        //ByteArrayOutputStream转成InputStream
        InputStream input = new ByteArrayInputStream(os.toByteArray());
        //InputStream转成MultipartFile
        multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return multipartFile;
}

到此这篇关于Java 截取视频资料中的某一帧作为缩略图的文章就介绍到这了,更多相关Java 视频缩略图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于IDEA建立module操作步骤解析

    基于IDEA建立module操作步骤解析

    这篇文章主要介绍了基于IDEA建立module操作步骤解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • 浅聊一下Spring中Bean的配置细节

    浅聊一下Spring中Bean的配置细节

    我们知道,当写完一个普通的 Java 类后,想让 Spring IoC 容器在创建类的实例对象时使用构造方法完成实例对象的依赖注入,那么就需要在配置元数据中写好类的 Bean 定义,包括各种标签的属性。所以本文我们来说说这其中的配置细节,需要的朋友可以参考下
    2023-07-07
  • Spring对静态变量无法注入的解决方案

    Spring对静态变量无法注入的解决方案

    这篇文章主要介绍了使用Spring对静态变量无法注入的解决方案,具有很好的参考价值,希望对大家有所帮助。
    2021-07-07
  • JVM 堆和栈的区别

    JVM 堆和栈的区别

    本文主要介绍了JVM堆和栈的区别。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Java Spring框架创建项目与Bean的存储与读取详解

    Java Spring框架创建项目与Bean的存储与读取详解

    本篇文章将介绍Spring项目的创建,IDEA国内源的配置以及Bean的存储与读取,所谓的Bean其实就是对象的意思,更详细地说Spring Bean是被实例的,组装的及被Spring 容器管理的Java对象
    2022-07-07
  • JavaWeb购物车项目开发实战指南

    JavaWeb购物车项目开发实战指南

    之前没有接触过购物车的东东,也不知道购物车应该怎么做,所以在查询了很多资料,总结一下购物车的功能实现,下面这篇文章主要给大家介绍了关于JavaWeb购物车项目开发的相关资料,需要的朋友可以参考下
    2022-06-06
  • Spring JPA联表查询之OneToOne源码详解

    Spring JPA联表查询之OneToOne源码详解

    这篇文章主要为大家介绍了Spring JPA联表查询之OneToOne源码详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 详解Java中二分法的基本思路和实现

    详解Java中二分法的基本思路和实现

    二分法是一个非常高效的算法,它常常用于计算机的查找过程中。本文将通过示例为大家详细讲讲二分法的基本思路和实现,感兴趣的可以了解一下
    2022-08-08
  • springboot集成sensitive-word实现敏感词过滤的两种方案

    springboot集成sensitive-word实现敏感词过滤的两种方案

    敏感词过滤通常是指从文本中检测并移除或替换掉被认为是不适当、冒犯性或违反特定社区准则的词汇,这篇文章主要介绍了springboot集成sensitive-word实现敏感词过滤,需要的朋友可以参考下
    2024-08-08
  • 全面汇总SpringBoot和SpringClould常用注解

    全面汇总SpringBoot和SpringClould常用注解

    Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能,这篇文章就带你来了解一下
    2021-08-08

最新评论