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

Comments

  1. Replies
    1. Awesome.. A must have functionality :)

      Delete
  2. can you please tell me where and how dependency is add
    reply me on my mail ajaybhaisare8@gmail.com

    ReplyDelete
    Replies
    1. Dependency needs to be added in pom file inside dependencies tag in case of maven project or needs to download jar file from maven repository

      Delete
  3. I tried to download jcodec from the path you said but I am not finding AWTUtil.java in the "src/main/java/org/jcodec/scale/" you said.
    How types of jar files I import also I am getting error like "FrameGrab cannot be resolved"

    ReplyDelete
  4. try with latest version of project

    org.jcodec
    jcodec
    0.2.3


    you may not need to do anything

    ReplyDelete
  5. Working code. Thanks a lot.

    ReplyDelete
  6. Thanks for a great tutorial!

    ReplyDelete

Post a Comment