【JavaCV】使用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)); } }
posted @ 2018-08-15 17:50  翠微  阅读(6342)  评论(0编辑  收藏  举报