java如何旋转视频文件_Java截取视频首帧并旋转正向

这段Java代码展示了如何使用javacv库从视频中截取首帧,并根据视频元数据进行旋转。适用于处理需要旋转的iPhone视频首帧问题。代码包括获取视频旋转角度、截取图片、等比例缩放以及旋转图片的步骤。
摘要由CSDN通过智能技术生成

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下失败,请使用以下依赖。

org.bytedeco

javacv

1.4.3

org.bytedeco.javacpp-presets

ffmpeg-platform

4.0.2-1.4.3

2、针对iphone手机视频等需要进行首帧图片旋转,否则出现首帧图片横着的情况。如代码部分:

String rotate_old=ff.getVideoMetadata("rotate");//视频旋转角度,可能是null

vue 截取视频第一帧

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

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

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

 $xiangmupath = $this->getxiangmupath(); $filename = 'chengs ...

使用javacv 截取视频指定帧节

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

Java截取视频文件缩略图

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

java获取视频的第一帧

//------------maven配置文件--------------- org.bytedeco

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

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

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

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

java获取视频播第一帧

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

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

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

随机推荐

GCD定时器

// // ViewController.m // GCD 定时器 // // #import "ViewController.h" NSInteger count = ; @in ...

【转~】初识贝塞尔曲线(B&&num;233&semi;zier curve)

本文图文大多转自http://www.html-js.com/article/1628 QAQ我居然去扒维基,,,看不懂啊,,,我要去补数学,,, 在做变形小鸡的时候用到CSS3 transition ...

一次有趣的XSS漏洞挖掘分析(3)最终篇

这真是最后一次了.真的再不逗这个程序员了.和预期一样,勤奋的程序员今天又更新程序了.因为前面写的payload都有一个致命的弱点,就是document.write()会完全破坏DOM结构.而且再“完事 ...

修改Delphi工具控件的默认字体

修改Delphi工具控件的默认字体: 注册表: Delphi 6:    HKEY_CURRENT_USER\Software\Borland\Delphi\6.0Delphi 7:    HKEY_ ...

Coreseek&colon;部门查询和增量索引代替实时索引

1.行业调查 索引系统需要通过主查询来获取所有的文档信息,一个简单的实现是整个表的数据到内存,但是这可能会导致整个表被锁定,并且使其它操作被阻止(例如:在MyISAM格款式上INSERT操作).同时, ...

&lbrack;Find the last digit when factorial of A divides factorial of B&rsqb;

Given two numbers A and B. The task is to compute the last digit of the resulting F, where F= B! / A ...

Divisibility by 25 CodeForces - 988E (技巧的暴力)

You are given an integer nn from 11 to 10181018 without leading zeroes. In one move you can swap any ...

2&period; Java内存区域

Java 虚拟机的内存模型分为两部分:一部分是线程共享的,包括 Java 堆和方法区:另一部分是线程私有的,包括虚拟机栈和本地方法栈,以及程序计数器这一小部分内存 2.1 程序计数器 程序计数器(Pr ...

&lpar;推荐&rpar;Skyline调用WMTS服务接口

文章地址 http://blog.csdn.net/chaiqi/article/details/9302373 供大家学习参考.

【kmp算法】uva11475 Extend to Palindrome

就把每个串倒过来,和原串匹配,看最后能匹配多少就行. #include #include #include ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值