Java 获取视频缩略图

简述

项目中需要获取视频的缩略图,并发和性能要求不够高,ffmpeg,javacv 配置比较麻烦,找了一个基本满足需求,比较轻量的工具 jcodec 。

示例

依赖:

<dependency>
    <groupId>org.jcodecgroupId>
    <artifactId>jcodecartifactId>
    <version>0.2.3version>
dependency>
<dependency>
    <groupId>org.jcodecgroupId>
    <artifactId>jcodec-javaseartifactId>
    <version>0.2.3version>
dependency>

代码:

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import org.jcodec.api.FrameGrab;
import org.jcodec.api.JCodecException;
import org.jcodec.common.model.Picture;
import org.jcodec.scale.AWTUtil;

public final class VideoUtils {

    private static final int THUMB_FRAME = 5;

    private VideoUtils() { }

    /**
     * 获取视频指定帧
     * @author sunk
     */
    public static BufferedImage getFrame (File file, int frameNumber)
            throws IOException, JCodecException {

        Picture picture = FrameGrab.getFrameFromFile(file, frameNumber);
        return AWTUtil.toBufferedImage(picture);
    }

    /**
     * 获取缩略图
     * @author sunk
     */
    public static ByteArrayOutputStream getThumbnail(File file,
            int limit) throws IOException, JCodecException {

        BufferedImage frameBi = getFrame(file, THUMB_FRAME);
        return ImageUtils.getThumbnail(frameBi, limit);
    }

    /**
     * 获取缩略图
     * @author sunk
     */
    public static ByteArrayOutputStream getThumbnail(File file)
            throws IOException, JCodecException {

        BufferedImage frameBi = getFrame(file, THUMB_FRAME);
        return ImageUtils.getThumbnail(frameBi);
    }
}
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;

public final class ImageUtils {

    //缩略图默认长宽限制
    private static final int THUMBNAIL_DEFAULT_LIMIT = 400;

    private ImageUtils() { }

    /**
     * 根据长宽值缩放
     * @author sunk
     */
    public static BufferedImage scaleByWh(BufferedImage source, int width, int height) {
        return getBufferedImageLocal(source.getScaledInstance(width, height, Image.SCALE_SMOOTH));
    }

    /**
     * 根据长宽限制缩放
     * 

限制较大的一边 * @author sunk */ public static BufferedImage scaleByWhLimit(BufferedImage source, int limit) { int scaleW = -1; int scaleH = -1; if (source.getWidth() > source.getHeight()) { scaleW = limit; } else { scaleH = limit; } return scaleByWh(source, scaleW, scaleH); } /** * 根据比例缩放 * @author sunk */ public static BufferedImage scaleByRatio(BufferedImage source, double ratio) { int w = (int) (source.getWidth() * ratio); int h = (int) (source.getHeight() * ratio); return scaleByWh(source, w, h); } /** * 将 Image 转为 BufferedImage * @author sunk */ public static BufferedImage getBufferedImage(Image img) { if (img instanceof BufferedImage) { return (BufferedImage) img; } BufferedImage bufImage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = bufImage.createGraphics(); g2d.drawImage(img, 0, 0, null); g2d.dispose(); return bufImage; } /** * 将 Image 转为 BufferedImage * @author sunk */ public static BufferedImage getBufferedImageLocal(Image img) { if (img instanceof BufferedImage) { return (BufferedImage) img; } GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); GraphicsConfiguration gc = gd.getDefaultConfiguration(); BufferedImage bufImage = gc.createCompatibleImage(img.getWidth(null), img.getHeight(null)); Graphics2D g2d = bufImage.createGraphics(); g2d.drawImage(img, 0, 0, null); g2d.dispose(); return bufImage; } /** * 获取缩略图 * @author sunk */ public static ByteArrayOutputStream getThumbnail(BufferedImage sourceBi, int limit) throws IOException { //缩放 BufferedImage scaledBi = scaleByWhLimit(sourceBi, limit); //压缩 ByteArrayOutputStream compressedOs = new ByteArrayOutputStream(); ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("jpg").next(); ImageWriteParam jpgWriteParam = jpgWriter.getDefaultWriteParam(); jpgWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); jpgWriteParam.setCompressionQuality(0.5f); jpgWriter.setOutput(ImageIO.createImageOutputStream(compressedOs)); jpgWriter.write(null, new IIOImage(scaledBi, null, null), jpgWriteParam); return compressedOs; } /** * 获取缩略图 * @author sunk */ public static ByteArrayOutputStream getThumbnail(BufferedImage sourceBi) throws IOException { return getThumbnail(sourceBi, THUMBNAIL_DEFAULT_LIMIT); } /** * 获取缩略图 * @author sunk */ public static ByteArrayOutputStream getThumbnail(File sourceFile, int limit) throws IOException { return getThumbnail(ImageIO.read(sourceFile), limit); } /** * 获取缩略图 * @author sunk */ public static ByteArrayOutputStream getThumbnail(File source) throws IOException { return getThumbnail(ImageIO.read(source)); } }

参考

1.JCodec
2.JCodec main repo

你可能感兴趣的:(----,----,Tool,Other,----,PL,-,Java)