package test;

import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet; import javax.imageio.ImageIO; import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter; public class VideoTest { public static String image_type="jpg";
public static String file_type="mp4"; public static void main(String[] args) {
String videofile="C:/xmqtest/test视频.mp4";//或网络视频地址
String framefileDir="C:/xmqtest/";
String targetFilePath=fetchFrame(videofile,framefileDir);
} /**
* 获取指定视频的帧并保存为图片至指定目录
* @param videofile 源视频文件路径
* @param framefile 截取帧的图片存放路径
* @throws Exception
*/
public static String fetchFrame(String videofile, String framefileDir){
try{
int startIndex=videofile.lastIndexOf('/');
String fileName;
if(startIndex==-1){
fileName=videofile.substring(videofile.lastIndexOf('\\')+1, videofile.lastIndexOf('.'));
}else{
fileName=videofile.substring(startIndex+1, videofile.lastIndexOf('.')+1);
}
String targetFileName=framefileDir+fileName+image_type;
File targetFile=createFile(targetFileName);
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
ff.start();
String rotate_old=ff.getVideoMetadata("rotate");//视频旋转角度,可能是null
int length = ff.getLengthInFrames();
int i = 0;
Frame f = null;
while (i < length) {
// 过滤前5帧,避免出现全黑的图片,依自己情况而定
f = ff.grabFrame();
if ((i > 5) && (f.image != null)) {
break;
}
i++;
}
// IplImage img = f.image;
int owidth = f.imageWidth;
int oheight = f.imageHeight;
// 对截取的帧进行等比例缩放
int width = 300;//生成图片宽度为300px
int height = (int) (((double) width / owidth) * oheight);
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage fecthedImage = converter.getBufferedImage(f);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH),
0, 0, null);
ImageIO.write(bi, image_type, targetFile);
ff.stop();
//有需要旋转
if(rotate_old!=null && !rotate_old.isEmpty()){
int rotate=Integer.parseInt(rotate_old);
rotatePhonePhoto(targetFileName,rotate);
}
return targetFileName;
}catch(Exception e){
e.printStackTrace();
}
return null;
}/***
* 创建文件,目录不存在则先创建目录在创建文件
* @param destFileName
* @return
*/
public static File createFile(String destFileName) {
try {
File file = new File(destFileName);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.createNewFile();
return file;
} catch (IOException e) {
e.printStackTrace();
return null;
}
} /**
* 删除单个文件
*/
public static void deleteFile(String sPath) {
File file = new File(sPath);
if (file.isFile() && file.exists()) {
file.delete();
}
} /**
* 旋转照片
*
* @return
*/
public static String rotatePhonePhoto(String fullPath, int angel) {
BufferedImage src;
try {
src = ImageIO.read(new File(fullPath));
int src_width = src.getWidth(null);
int src_height = src.getHeight(null); int swidth = src_width;
int sheight = src_height; if (angel == 90 || angel == 270) {
swidth = src_height;
sheight = src_width;
}
Rectangle rect_des = new Rectangle(new Dimension(swidth, sheight));
BufferedImage res = new BufferedImage(rect_des.width, rect_des.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = res.createGraphics();
g2.translate((rect_des.width - src_width) / 2, (rect_des.height - src_height) / 2);
g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);
g2.drawImage(src, null, null);
ImageIO.write(res,image_type, new File(fullPath));
} catch (Exception e) {
e.printStackTrace();
}
return fullPath; }
}

说明点:

1、加入依赖,经测试两个依赖在windows环境,linux环境下正常使用。如果本地windows环境正常但是在linux下失败,请使用以下依赖。

<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.3</version>
</dependency> <dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.0.2-1.4.3</version>
</dependency> 2、针对iphone手机视频等需要进行首帧图片旋转,否则出现首帧图片横着的情况。如代码部分:
String rotate_old=ff.getVideoMetadata("rotate");//视频旋转角度,可能是null

Java截取视频首帧并旋转正向的更多相关文章

  1. vue 截取视频第一帧

    最近自己写项目,在项目中涉及功能点又截取视频帧的点:需求澄清:移动端封面展示,平台上传图片(多张上传)取第一张上传图片为封面图:如上传视频则截取视频第一帧作为封面图: 实现思路:h5  video标签 ...

  2. php ffmpeg截取视频第一帧保存为图片的方法

    php ffmpeg截取视频第一帧保存为图片的方法 <pre> $xiangmupath = $this->getxiangmupath(); $filename = 'chengs ...

  3. 使用javacv 截取视频指定帧节

    个人博客 地址:https://www.wenhaofan.com/article/20190407105818 引入依赖 <dependency> <groupId>org. ...

  4. Java截取视频文件缩略图

    /** * 截取视频第0帧的图片 */public static void videoImage(String filePath, String fileName,int widthdist, int ...

  5. java获取视频的第一帧

    //------------maven配置文件--------------- <dependency> <groupId>org.bytedeco</groupId> ...

  6. 【Java SE】使用Javacv截取视频图片

    [Java Web开发学习]使用Javacv截取视频图片 转载:https://www.cnblogs.com/yangchongxing/p/9482935.html github地址:https: ...

  7. 用java实现给图片增加图片水印或者文字水印(也支持视频图像帧添加水印)

    javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置.大小.粗度.翻转.平滑等操作 javaCV图像处理之2:实时视频添加图片水 ...

  8. java获取视频播第一帧

    FFMPEG 功能很强大,做视频必备的软件.大家可通过 http://ffmpeg.org/ 了解.Windows版本的软件,可通过 http://ffmpeg.zeranoe.com/builds/ ...

  9. python opencv 按一定间隔截取视频帧

    前言关于opencvOpenCV 是 Intel 开源计算机视觉库 (Computer Version) .它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. ...

随机推荐

  1. Xcode 6 创建 Empty Application

    1.创建一个 Single View Application: 2.删除工程目录下的 Main.storyboard 和 LaunchScreen.xib: 3.打开 Supporting Files ...

  2. vue 使用element-ui实现城市三级联动

    <template> <div> <el-select v-model="prov" style="width:167px;margin-r ...

  3. C++系统学习之七:类

    类的基本思想是数据抽象和封装. 数据抽象是一种依赖于接口和实现分离的编程技术.类的接口包括用户所能执行的操作:类的实现包括类的数据成员.负责接口实现的函数体以及定义类所需的各种私有函数. 封装实现了类 ...

  4. bzoj5368 [Pkusc2018]真实排名

    题目描述: bz luogu 题解: 组合数计数问题. 首先注意排名指的是成绩不小于他的选手的数量(包括他自己). 考虑怎么增大才能改变排名. 小学生都知道,对于成绩为$x$的人,让他自己不动并让$\ ...

  5. [LUOGU] 1002 过河卒

    题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为"马拦过 ...

  6. SVN 如何提交 SO 库文件

    今天提交代码时候发现,svn add 还是 svn st 均查看不到想要提交的 so 文件. 后来才知道原来是配置文件出了问题,把so文件的提交给屏蔽掉了. 修改步骤如下: 1.Ubuntu 系统,点 ...

  7. 【HDU 2126】Buy the souvenirs(01背包)

    When the winter holiday comes, a lot of people will have a trip. Generally, there are a lot of souve ...

  8. 【RAID】raid1 raid2 raid5 raid6 raid10的优缺点和做各自raid需要几块硬盘

    Raid 0:一块硬盘或者以上就可做raid0优势:数据读取写入最快,最大优势提高硬盘容量,比如3快80G的硬盘做raid0 可用总容量为240G.速度是一样.缺点:无冗余能力,一块硬盘损坏,数据全无 ...

  9. maven 打某一个模块的包

    mvn clean mvn clean install -pl benefit-microservice-gateway -am -Dmaven.test.skip=true

  10. iOS WKWebView

    Webkit 是 iOS 8.0 后提供的新的框架,组件WKWebView比较UIWebView 速度更快.占用内存更少了,可支持性更多 WKWebView可通过KVO监听属性 title.estim ...