【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)); } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM