使用javacv生成视频缩略图-缩略图不显示文件名

一、创建项目

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. }

使用javacv生成视频缩略图

推荐阅读