关山难越,谁悲失路之人;萍水相逢,尽是他乡之客。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程教程 > HTML/CSS > 正文

使用javacv生成视频缩略图(java实现视频压缩)

guanshanw 2023-02-21 09:44 294 浏览 1 评论

一、创建项目

1、创建Maven项目

2、添加依赖

在pom.xml中添加依赖配置,具体如下:

[html] view plain copy

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.bytedeco</groupId>
  4. <artifactId>javacv-platform</artifactId>
  5. <version>1.3.1</version>
  6. </dependency>
  7. </dependencies>

二、具体实现

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

[java] view plain copy

  1. package com.lyz.medis.image;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.Collections;
  7. import java.util.List;
  8. import javax.imageio.ImageIO;
  9. import org.bytedeco.javacpp.opencv_core;
  10. import org.bytedeco.javacpp.opencv_core.IplImage;
  11. import org.bytedeco.javacv.FFmpegFrameGrabber;
  12. import org.bytedeco.javacv.Frame;
  13. import org.bytedeco.javacv.FrameGrabber.Exception;
  14. import org.bytedeco.javacv.Java2DFrameConverter;
  15. import org.bytedeco.javacv.OpenCVFrameConverter;
  16. /**
  17. * 获取视频缩略图
  18. * @author liuyazhuang
  19. *
  20. */
  21. public class VideoImage {
  22. private static final String IMAGEMAT = "png";
  23. private static final String ROTATE = "rotate";
  24. /**
  25. * 默认截取视频的中间帧为封面
  26. */
  27. public static final int MOD = 2;
  28. public static void main(String[] args) throws Exception {
  29. System.out.println(randomGrabberFFmpegImage("C:/lyz/1522372294724_79583.mov", 2));
  30. }
  31. /**
  32. * 获取视频缩略图
  33. * @param filePath:视频路径
  34. * @param mod:视频长度/mod获取第几帧
  35. * @throws Exception
  36. */
  37. public static String randomGrabberFFmpegImage(String filePath, int mod) throws Exception {
  38. String targetFilePath = "";
  39. FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
  40. ff.start();
  41. String rotate = ff.getVideoMetadata(ROTATE);
  42. int ffLength = ff.getLengthInFrames();
  43. Frame f;
  44. int i = 0;
  45. int index = ffLength / mod;
  46. while (i < ffLength) {
  47. f = ff.grabImage();
  48. if(i == index){
  49. if (null != rotate && rotate.length() > 1) {
  50. OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
  51. IplImage src = converter.convert(f);
  52. f = converter.convert(rotate(src, Integer.valueOf(rotate)));
  53. }
  54. targetFilePath = getImagePath(filePath, i);
  55. doExecuteFrame(f, targetFilePath);
  56. break;
  57. }
  58. i++;
  59. }
  60. ff.stop();
  61. return targetFilePath;
  62. }
  63. /**
  64. * 根据视频路径生成缩略图存放路径
  65. * @param filePath:视频路径
  66. * @param index:第几帧
  67. * @return:缩略图的存放路径
  68. */
  69. private static String getImagePath(String filePath, int index){
  70. if(filePath.contains(".") && filePath.lastIndexOf(".") < filePath.length() - 1){
  71. filePath = filePath.substring(0, filePath.lastIndexOf(".")).concat("_").concat(String.valueOf(index)).concat(".").concat(IMAGEMAT);
  72. }
  73. return filePath;
  74. }
  75. /**
  76. * 旋转图片
  77. * @param src
  78. * @param angle
  79. * @return
  80. */
  81. public static IplImage rotate(IplImage src, int angle) {
  82. IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
  83. opencv_core.cvTranspose(src, img);
  84. opencv_core.cvFlip(img, img, angle);
  85. return img;
  86. }
  87. /**
  88. * 截取缩略图
  89. * @param f
  90. * @param targerFilePath:封面图片
  91. */
  92. public static void doExecuteFrame(Frame f, String targerFilePath) {
  93. if (null == f || null == f.image) {
  94. return;
  95. }
  96. Java2DFrameConverter converter = new Java2DFrameConverter();
  97. BufferedImage bi = converter.getBufferedImage(f);
  98. File output = new File(targerFilePath);
  99. try {
  100. ImageIO.write(bi, IMAGEMAT, output);
  101. } catch (IOException e) {
  102. e.printStackTrace();
  103. }
  104. }
  105. /**
  106. * 根据视频长度随机生成随机数集合
  107. * @param baseNum:基础数字,此处为视频长度
  108. * @param length:随机数集合长度
  109. * @return:随机数集合
  110. */
  111. public static List<Integer> random(int baseNum, int length) {
  112. List<Integer> list = new ArrayList<Integer>(length);
  113. while (list.size() < length) {
  114. Integer next = (int) (Math.random() * baseNum);
  115. if (list.contains(next)) {
  116. continue;
  117. }
  118. list.add(next);
  119. }
  120. Collections.sort(list);
  121. return list;
  122. }
  123. }

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

[java] view plain copy

  1. package com.lyz.medis.image;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.Collections;
  7. import java.util.List;
  8. import javax.imageio.ImageIO;
  9. import org.bytedeco.javacpp.opencv_core;
  10. import org.bytedeco.javacpp.opencv_core.IplImage;
  11. import org.bytedeco.javacv.FFmpegFrameGrabber;
  12. import org.bytedeco.javacv.Frame;
  13. import org.bytedeco.javacv.FrameGrabber.Exception;
  14. import org.bytedeco.javacv.Java2DFrameConverter;
  15. import org.bytedeco.javacv.OpenCVFrameConverter;
  16. /**
  17. * 获取图片缩略图
  18. * @author liuyazhuang
  19. *
  20. */
  21. public abstract class VideoImageFrame {
  22. public static void main(String[] args) throws Exception {
  23. randomGrabberFFmpegImage("e:/lyz/ffmpeg.mp4", "./target", "screenshot", 5);
  24. }
  25. /**
  26. * 生成图片缩略图
  27. * @param filePath:视频完整路径
  28. * @param targerFilePath:缩略图存放目录
  29. * @param targetFileName:缩略图文件名称
  30. * @param randomSize:生成随机数的数量
  31. * @throws Exception
  32. */
  33. public static void randomGrabberFFmpegImage(String filePath, String targerFilePath, String targetFileName, int randomSize) throws Exception {
  34. FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(filePath);
  35. ff.start();
  36. String rotate = ff.getVideoMetadata("rotate");
  37. int ffLength = ff.getLengthInFrames();
  38. List<Integer> randomGrab = random(ffLength, randomSize);
  39. int maxRandomGrab = randomGrab.get(randomGrab.size() - 1);
  40. Frame f;
  41. int i = 0;
  42. while (i < ffLength) {
  43. f = ff.grabImage();
  44. if (randomGrab.contains(i)) {
  45. if (null != rotate && rotate.length() > 1) {
  46. OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
  47. IplImage src = converter.convert(f);
  48. f = converter.convert(rotate(src, Integer.valueOf(rotate)));
  49. }
  50. doExecuteFrame(f, targerFilePath, targetFileName, i);
  51. }
  52. if (i >= maxRandomGrab) {
  53. break;
  54. }
  55. i++;
  56. }
  57. ff.stop();
  58. }
  59. /**
  60. * 旋转图片
  61. * @param src:图片
  62. * @param angle:旋转角度
  63. * @return
  64. */
  65. public static IplImage rotate(IplImage src, int angle) {
  66. IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
  67. opencv_core.cvTranspose(src, img);
  68. opencv_core.cvFlip(img, img, angle);
  69. return img;
  70. }
  71. /**
  72. * 生成缩略图
  73. * @param f Frame对象
  74. * @param targerFilePath
  75. * @param targetFileName
  76. * @param index
  77. */
  78. public static void doExecuteFrame(Frame f, String targerFilePath, String targetFileName, int index) {
  79. if (null == f || null == f.image) {
  80. return;
  81. }
  82. Java2DFrameConverter converter = new Java2DFrameConverter();
  83. String imageMat = "png";
  84. String FileName = targerFilePath + File.separator + targetFileName + "_" + index + "." + imageMat;
  85. BufferedImage bi = converter.getBufferedImage(f);
  86. File output = new File(FileName);
  87. try {
  88. ImageIO.write(bi, imageMat, output);
  89. } catch (IOException e) {
  90. e.printStackTrace();
  91. }
  92. }
  93. /**
  94. * 随机生成随机数集合
  95. * @param baseNum:随机种子
  96. * @param length:随机数集合长度
  97. * @return:随机数集合
  98. */
  99. public static List<Integer> random(int baseNum, int length) {
  100. List<Integer> list = new ArrayList<>(length);
  101. while (list.size() < length) {
  102. Integer next = (int) (Math.random() * baseNum);
  103. if (list.contains(next)) {
  104. continue;
  105. }
  106. list.add(next);
  107. }
  108. Collections.sort(list);
  109. return list;
  110. }
  111. }

相关推荐

Web前端培训:五种JavaScript富文本编辑器的比较

开发自己的基于web的文本编辑器背后可能有不同的原因,但是,你总能找到一个工具来创建符合你的需求和资金的在线文本编辑器。在本文中,我们将简要回顾五个JavaScript富文本编辑器,帮助你找到满足期望...

前端开发教程之计算机基础知识

前端开发工程师,是时下很火的一个职业,不仅适合男生也合适女生;想从事软件行业,成为程序员、程序媛;前端开发工程师是介入工程开发的很好的一个入口,今天小编带大家进入前端开发,本文涉及入门html、cs...

vue.js简单前端感想

目前前端框架五花八门,从传统的javascript到现在的angularvuereact,再到flux等等。个人觉得重要的不是掌握好多门前端技术,重要的是打好javascript基础。现在越来越多...

16岁全栈开发者:我从开发游戏到写加密货币投资机器人的心路历程

选自Medium作者:NunoMartins机器之心编译参与:LuoSainan、一鸣全栈开发者听起来是个很高大上的程序员岗位,似乎没有几年工作经验是Hold不住的。但是,有个葡萄牙少年16...

微软推出 VSCode 新特性,为 TS 和 JS 用户提供 AI 辅助开发功能

除了开发人员非常喜欢的IntelliSense和代码完成之外,今年早些时候,微软还发布了IntelliCode,提供了一组AI辅助开发功能。VSCode团队现在宣布了一项新的实验性扩展,将I...

JavaScript主流框架3月趋势总结

框架使用情况我们首先来看看主流框架的使用趋势。下图显示了前四大框架(Angular,AngularJS,React和Vue)最近一个月的npm下载量趋势。你可以点击查看大图。框架增长率(上个月)增...

webstorm是什么软件

●WebStorm是一款由JetBrains开发的集成开发环境(IDE),它是专门为开发Web应用程序而设计的。它提供了许多功能,例如代码自动完成、错误突出显示、重构、调试、版本控制等,可...

认识Vue

什么是VueVue.js是一套用于构建用户界面的渐进式JavaScript框架,也是一个创建单页应用的Web应用框架。与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用。Vue...

Java的未来在哪里

我是码农小胖哥。天天有编程干货分享。觉得写的不错可以点个赞,转发一下,关注一下。Java已经流行很多年了。很多的新兴语言都以Java作为标杆。那么Java主要在哪些场景使用呢?用于Web编程大...

jQuery 都过时了,那还学它干嘛

请问现在我还需要学习jQuery吗?听你在知乎说jQuery已经过时了,是不是就不用学了?短答案:jQuery还是可以学一学的,学了之后对写代码和封装库很有帮助。现在的「新人」依然可以学习...

一碟Vue小菜,您确定不要尝尝吗?

各位小伙伴,好长时间不见了,大家都过得怎么样?小编最近一直在忙新工作的事情,换了工作又要花一段时间适应,而且新项目的工作挺重的,每天加班都要加到八九点,而且当然是没有加班费的啦。不开心虽然最近没有写文...

前端培训哪个机构比较好?

目前,前端开发领域非常热门,前端工程师是IT行业中非常抢手的职业之一。前端技术不断地发展和变化,需要不断地学习和更新知识。因此,如果你的前端技能过硬且经验丰富那么工作机会还是有很多的。那么有很多小伙伴...

在八维教育,网站工程专业中教授的web前端框架有哪些?

在八维教育,网站工程专业中教授的web前端框架有哪些?这是一个问题,也是很多人关心的话题。1:web前端框架的定义Web前端框架,通常指的是由一群人搭建一个网站,他们能够通过简单的代码编写出优美的网页...

花了几天时间,把 Vue 改成了 Angular

最近规划一款预期规模会比较大、有较高复杂程度的企业级产品,Web框架最终选择了Vue。可以考虑的Web框架,基本就是众所周知的那三个:Angular最严谨,API很规范,一看就是大厂的作品...

React、Vue、Angular 经典前端框架讲解

前端框架是一种用于简化Web应用程序开发的工具。它们通过提供一些常用功能和组件来加速开发速度和提高代码质量。捷云介绍三种经典前端框架:React、Vue和Angular,并分析它们的优缺点。一...

已有1位网友发表了看法:

取消回复欢迎 发表评论: