【Java SE】使用Javacv截取视频图片
【Java Web开发学习】使用Javacv截取视频图片
转载:https://www.cnblogs.com/yangchongxing/p/9482935.html
github地址:https://github.com/bytedeco/javacv
Java不擅长处理视频和图片。使用场景是上传上来的视屏需要一个封面,所以就用java实现了。
javacv文档很少,参考网上的代码稍作修改而成,仅供参考,有好的方式欢迎留言。
网上有好多没有解决截屏图片被旋转过的问题,使用String rotate = grabber.getVideoMetadata("rotate");获取视频有没有旋转,没有返回null,有返回度数,90,180,270等。把图片做对象旋转,图片就正了。
示例代码:select截取第20帧的图片
public static void main(String[] args) throws IOException {
// 截第20帧
int select = 20;
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("E:/wx/下.mp4");
grabber.start();
int length = grabber.getLengthInFrames();
int index = 1;
Frame frame = null;
while (index <= length) {
frame = grabber.grab();
if (index >= select) {
break;
}
index++;
}
String rotate = grabber.getVideoMetadata("rotate");
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.getBufferedImage(frame);
if (rotate != null) {
//旋转图片
bi = rotate(bi, Integer.parseInt(rotate));
}
ImageIO.write(bi, "jpg", new File("E:/wx/" + System.currentTimeMillis() + ".jpg"));
grabber.stop();
}
public static BufferedImage rotate(BufferedImage src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
int type = src.getColorModel().getTransparency();
Rectangle rect_des = calcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type);
Graphics2D g2 = bi.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, 0, 0, null);
g2.dispose();
return bi;
}
public static Rectangle calcRotatedSize(Rectangle src, int angel) {
if (angel >= 90) {
if(angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new java.awt.Rectangle(new Dimension(des_width, des_height));
}
下面是一个上传截取第一帧做图片
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest; import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.support.DefaultMultipartHttpServletRequest; @RequestMapping("/upload")
@Controller
public class UploadController extends BaseController {
// 图片上传
@RequestMapping(value="/image", method=RequestMethod.POST, produces="application/json;charset=UTF-8")
@ResponseBody
public String uploadImage(@RequestParam(value = "imageFile", required = false) CommonsMultipartFile imageFile, HttpServletRequest request) throws IOException {
if (imageFile == null || imageFile.getSize() == 0) {
DefaultMultipartHttpServletRequest multipartRequest = (DefaultMultipartHttpServletRequest)request;
imageFile = (CommonsMultipartFile) multipartRequest.getFile("Filedata");
if (imageFile == null || imageFile.getSize() == 0) {
Result result = new Result();
result.setStatus(Result.STATUS_FAILURE);
result.setMessage(Result.STATUS_FAILURE);
return result.toJson();
}
}
//文件名
String fileName = Utils.fileName() + Utils.suffix(imageFile.getOriginalFilename());
//日期目录
String path = "/uploads/images" + new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
//服务器图片文件存放目录
String serverPath = request.getServletContext().getRealPath(path); File serverPathFile = new File(serverPath);
//目录不存在则创建
if (!serverPathFile.exists()) {
serverPathFile.mkdirs();
}
String imageUrl = path + fileName;
String serverFilePath = serverPath + fileName;
//移动文件
imageFile.transferTo(new File(serverFilePath));return imageUrl;
}
// 视频上传
@SuppressWarnings("resource")
@RequestMapping(value="/video", method=RequestMethod.POST, produces="application/json;charset=UTF-8")
@ResponseBody
public String uploadVideo(@RequestParam(value = "videoFile", required = false) CommonsMultipartFile imageFile, HttpServletRequest request) throws IOException {
if (imageFile == null || imageFile.getSize() == 0) {
Result result = new Result();
result.setStatus(Result.STATUS_FAILURE);
result.setMessage("文件不存在");
return result.toJson();
}
//文件名
String fileName = Utils.fileName() + Utils.suffix(imageFile.getOriginalFilename());
//日期目录
String path = "/uploads/videos" + new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
//服务器图片文件存放目录
String serverPath = request.getServletContext().getRealPath(path); File serverPathFile = new File(serverPath);
//目录不存在则创建
if (!serverPathFile.exists()) {
serverPathFile.mkdirs();
}
String serverFilePath = serverPath + fileName;
//移动文件
imageFile.transferTo(new File(serverFilePath)); //视频截屏
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(serverFilePath);
grabber.start();
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.convert(grabber.grab());
String rotate = grabber.getVideoMetadata("rotate");
if (rotate != null) {
bi = rotate(bi, Integer.parseInt(rotate));
}
fileName += ".v.jpg";
serverFilePath = serverPath + fileName;
String imageUrl = path + fileName;
ImageIO.write(bi, "jpg", new File(serverFilePath));
grabber.stop();
// 返回截取封面
return imageUrl;
} public static BufferedImage rotate(BufferedImage src, int angel) {
int src_width = src.getWidth(null);
int src_height = src.getHeight(null);
int type = src.getColorModel().getTransparency();
Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(src_width, src_height)), angel);
BufferedImage bi = new BufferedImage(rect_des.width, rect_des.height, type);
Graphics2D g2 = bi.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, 0, 0, null);
g2.dispose();
return bi;
}
public static Rectangle CalcRotatedSize(Rectangle src, int angel) {
if (angel >= 90) {
if(angel / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angel = angel % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height); int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha - angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new java.awt.Rectangle(new Dimension(des_width, des_height));
}
}
【Java SE】使用Javacv截取视频图片的更多相关文章
- C#利用开源软件ffMpeg截取视频图片
#region 从视频画面中截取一帧画面为图片 /// <summary> /// 从视频画面中截取一帧画面为图片 /// </summary> /// <param n ...
- 使用javacv 截取视频指定帧节
个人博客 地址:https://www.wenhaofan.com/article/20190407105818 引入依赖 <dependency> <groupId>org. ...
- (转载)[FFmpeg]使用ffmpeg从各种视频文件中直接截取视频图片
你曾想过从一个视频文件中提取图片吗?在Linux下就可以,在这个教程中我将使用ffmpeg来从视频中获取图片. 什么是ffmpeg?What is ffmpeg? ffmpeg是一个非常有用的命令行程 ...
- iOS截取视频缩略图的两种方法
前言: 看完了使用MPMoviePlayerController播放在线视频,在实际应用中有时候须要获取视频的缩略图,我们来看看怎样截取指定时间内的视频缩略图. 一 使用MPMoviePlayerC ...
- FFmpeg-截取视频图片
FFmpeg-截取视频图片 标签(空格分隔): linux 安装FFmpeg 官网:http://www.ffmpeg.org/ 这里主要是linux环境下的安装 1. wget http://ffm ...
- javacv——读取摄像头的图像、截取视频的画面
javacv开发包是用于支持java多媒体开发的一套开发包,可以适用于本地多媒体(音视频)调用以及音视频,图片等文件后期操作(图片修改,音视频解码剪辑等等功能). 这些需要引入的包.音视频处理使用ff ...
- javacpp-opencv图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作
欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) javaCV图像处理系列: javaCV图像处理之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体.位置. ...
- Java截取视频文件缩略图
/** * 截取视频第0帧的图片 */public static void videoImage(String filePath, String fileName,int widthdist, int ...
- php ffmpeg截取视频第一帧保存为图片的方法
php ffmpeg截取视频第一帧保存为图片的方法 <pre> $xiangmupath = $this->getxiangmupath(); $filename = 'chengs ...
随机推荐
- 五分钟学会HTML5的WebSocket协议
1.背景 很多网站为了实现推送技术,所用的技术都是Ajax轮询.轮询是在特定的的时间间隔由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器.这种传统的模式带来很明显的缺点 ...
- 领扣(LeetCode)3的幂 个人题解
给定一个整数,写一个函数来判断它是否是 3 的幂次方. 示例 1: 输入: 27 输出: true 示例 2: 输入: 0 输出: false 示例 3: 输入: 9 输出: true 示例 4: 输 ...
- C语言1博客作业01
1 你对软件工程专业或者计算机科学与技术专业了解是怎样? 主修大数据技术导论.数据采集与处理实践(Python).Web前/后端开发.统计与数据分析.机器学习.高级数据库系统.数据可视化.云计算技术. ...
- IBM-X3850-4U诊断面板信息
IBM X3850 4U 指示灯 描述 OVERSPEC 没有足够的电量为系统供电.NONRED和LOG指示灯可能也点亮 PS 一个电源故障或者被电源未插 LINK 保留 CPU CPU出现故障.丢失 ...
- gdb(ddd,kdevelop等)调试ZeroIce开发的应用程序,中断信号引起的问题
不作文,只记要点. 1.Ice::Application的程序框架默认对SIGHUP, SIGINT, SIGTERM进行处理.目的就是捕捉Ctrl+C发出信号有序地结束程序.这个功能扰乱了我们使用g ...
- opencv 4 图像处理 (1 线性滤波,非线性滤波)
1 线性滤波:方框滤波.均值滤波.高斯滤波 1.1方框滤波(box Filter) 1.2均值滤波(blur函数) 缺陷: 1.3高斯滤波(GaussianBlur函数) 1.4线性滤波核心API函数 ...
- tensorflow学习笔记——模型持久化的原理,将CKPT转为pb文件,使用pb模型预测
由题目就可以看出,本节内容分为三部分,第一部分就是如何将训练好的模型持久化,并学习模型持久化的原理,第二部分就是如何将CKPT转化为pb文件,第三部分就是如何使用pb模型进行预测. 一,模型持久化 为 ...
- BIOS和CMOS概念整理
一:什么是BIOS BIOS(Basic Input Output System),基本输入输出系统.是被写死在主板ROM只读芯片中的一组程序,在开机的时候首先要去读取的一个小程序. 它是我们可以将 ...
- js如何衔接css3的多个@keyframes动画?
css3特效动画,我们在编写页面中经常遇到,而且是在同一个div模块上有多个衔接的不同动画,css中,我们经常使用animation-delay (规定在动画开始之前的延迟)进行处理. 那么,下面分享 ...
- lvm_lv_create
lvm lv create 开机自动挂载 neokylinV7.0 [root@localhost ~]# fdisk -l 磁盘 /dev/vda:322.1 GB, 322122547200 字 ...