想要查看前面的笔记请翻阅我的CSDN博客,作者码字不易,喜欢的话点赞,加个关注吧,后期还有很多干货等着你!
先说需求:将上传后的视频,获取其中一帧数,制作成截图,保存下来;
遇到问题:截图保存下来后会出现图片翻转或者是倾斜90°的问题
我一开始以为是ffmpeg的问题,后来经过多方搜寻,最后是B乎上的老哥给了我灵感
最后也顺利完成了代码的修改:
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 javax.imageio.ImageIO;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.web.multipart.MultipartFile;
public class PicFetch {
public static String image_type="jpg";
public static String file_type="mp4";
// public static void main(String[] args) {
// String videofile="F:\\file\\aa.MOV";//或网络视频地址
// String framefileDir="F:\\file\\img";
//
// String targetFilePath=fetchFrame(videofile,framefileDir);
// System.out.println(targetFilePath);
// }
/**
* 获取指定视频的帧并保存为图片至指定目录
* @param videofile 源视频文件路径
* @param framefileDir 截取帧的图片存放路径
* @throws Exception
*/
public static String fetchFrame(MultipartFile videofile, String framefileDir){
try{
String originalFilename = videofile.getOriginalFilename();
String[] split = originalFilename.split("\\.");
File file = Unite.multipartFileToFile(videofile);
// 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+split[0]+ "."+image_type;
File targetFile=createFile(targetFileName);
FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(file);
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++;
}
int owidth = f.imageWidth;
int oheight = f.imageHeight;
// 对截取的帧进行等比例缩放
int width = 800;//生成图片宽度为800px
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);
}
if (file.delete()){
System.out.println("删除备份视频成功");
}else {
System.out.println("删除备份视频失败");
}
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;
}
}
/**
* 删除单个文件
* @param sPath
*/
public static void deleteFile(String sPath) {
File file = new File(sPath);
if (file.isFile() && file.exists()) {
file.delete();
}
}
/**
* 旋转照片
* @param fullPath
* @param angel
* @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;
}
}
主要就是:先获取截图的角度,发现有翻转情况后,再扭转回来
String rotate_old=ff.getVideoMetadata("rotate");//视频旋转角度,可能是null
if(rotate_old!=null && !rotate_old.isEmpty()){
int rotate=Integer.parseInt(rotate_old);
rotatePhonePhoto(targetFileName,rotate);
}