Friday, 3 June 2016

How to extract Single Frame as an Image file from a Video (mp4 format) [JCodec – Java library example]

1.       You need to go to https://github.com/jcodec/jcodec
a.       Then you need to download Jcodec 0.2.0 library source code. 
b.      Compile inside directory [jcodec-master] the project --- mvn clean install
c.       Go to location "src/main/java/org/jcodec/scale/AWTUtil.java"
     -- in this class you can find utility methods which i am using below.
2.       Add maven dependency
a.       <dependency>
    <
groupId>org.jcodec</groupId>
    <
artifactId>jcodec</artifactId>
    <
version>0.2.0</version>
</
dependency>
3.       This is the sample code to extract frame from video mp4 format

-          This works fine for me, hope this help you as well


  import org.jcodec.api.FrameGrab8Bit;
  import org.jcodec.api.JCodecException;
  import org.jcodec.common.model.ColorSpace;
  import org.jcodec.common.model.Picture8Bit;
  import org.jcodec.scale.ColorUtil;
  import org.jcodec.scale.RgbToBgr8Bit;
  import org.jcodec.scale.Transform8Bit;
  import javax.imageio.ImageIO;
  import java.awt.image.BufferedImage;
  import java.awt.image.DataBufferByte;
  import java.io.File;
  import java.io.IOException;
  import java.nio.file.Paths;

  public class VideoFrameExtracter {
    public File createThumbnailFromVideo(File file, int frameNumber) throws IOException, JCodecException {
        Picture8Bit frame = FrameGrab8Bit.getFrameFromFile(file, frameNumber);
        File tempFile = File.createTempFile("thumb_" + frameNumber + file.getName().replaceAll("(.+)\\..+", "$1"), ".png");
        ImageIO.write(toBufferedImage8Bit(frame), "png", tempFile);
        return tempFile;
    }
    // this method is from Jcodec AWTUtils.java.
    private BufferedImage toBufferedImage8Bit(Picture8Bit src) {
        if (src.getColor() != ColorSpace.RGB) {
            Transform8Bit transform = ColorUtil.getTransform8Bit(src.getColor(), ColorSpace.RGB);
            if (transform == null) {
                throw new IllegalArgumentException("Unsupported input colorspace: " + src.getColor());
            }
            Picture8Bit out = Picture8Bit.create(src.getWidth(), src.getHeight(), ColorSpace.RGB);
            transform.transform(src, out);
            new RgbToBgr8Bit().transform(out, out);
            src = out;
        }
        BufferedImage dst = new BufferedImage(src.getCroppedWidth(), src.getCroppedHeight(),
                BufferedImage.TYPE_3BYTE_BGR);
        if (src.getCrop() == null)
            toBufferedImage8Bit2(src, dst);
        else
            toBufferedImageCropped8Bit(src, dst);
        return dst;
    }
    // this method is from Jcodec AWTUtils.java.
    private void toBufferedImage8Bit2(Picture8Bit src, BufferedImage dst) {
        byte[] data = ((DataBufferByte) dst.getRaster().getDataBuffer()).getData();
        byte[] srcData = src.getPlaneData(0);
        for (int i = 0; i < data.length; i++) {
            data[i] = (byte) (srcData[i] + 128);
        }
    }
    // this method is from Jcodec AWTUtils.java.
    private static void toBufferedImageCropped8Bit(Picture8Bit src, BufferedImage dst) {
        byte[] data = ((DataBufferByte) dst.getRaster().getDataBuffer()).getData();
        byte[] srcData = src.getPlaneData(0);
        int dstStride = dst.getWidth() * 3;
        int srcStride = src.getWidth() * 3;
        for (int line = 0, srcOff = 0, dstOff = 0; line < dst.getHeight(); line++) {
            for (int id = dstOff, is = srcOff; id < dstOff + dstStride; id += 3, is += 3) {
                data[id] = (byte) (srcData[is] + 128);
                data[id + 1] = (byte) (srcData[is + 1] + 128);
                data[id + 2] = (byte) (srcData[is + 2] + 128);
            }
            srcOff += srcStride;
            dstOff += dstStride;
        }
    }
    public static void main(String[] args) {
        VideoFrameExtracter videoFrameExtracter = new VideoFrameExtracter();
        File file = Paths.get("C:\\Users\\Public\\Videos\\Sample Videos\\sample.mp4").toFile();
        try {
            File imageFrame = videoFrameExtracter.createThumbnailFromVideo(file, 2);
            System.out.println("input file name : " + file.getAbsolutePath());
            System.out.println("output video frame file name  : " + imageFrame.getAbsolutePath());
        } catch (IOException | JCodecException e) {
            System.out.println("error occurred while extracting image : " + e.getMessage());
        }
    }
}