Extrair imagem (frame) de um vídeo em Java com JavaCV

Você está com dificuldades para extrair uma imagem (frame) de um vídeo em Java? Neste artigo iremos apresentar a integração e configuração utilizando a API JavaCV. Então vamos lá!

O que é a biblioteca JavaCV?

JavaCV uses wrappers from the JavaCPP Presets of commonly used libraries by researchers in the field of computer vision (OpenCV, FFmpeg, libdc1394, PGR FlyCapture, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, and flandmark), and provides utility classes to make their functionality easier to use on the Java platform, including Android.

Em resumo essa biblioteca nos ajuda a manipular vídeos, imagens, etc. Bem vamos ao que interessa! Você pode encontrar tudo sobre essa biblioteca aqui: https://github.com/bytedeco/javacv , ou você pode deixar sua dúvida nos comentários abaixo, beleza?

Show me the Code!

Ah! Não esqueça de fazer o import da biblioteca, para isto exite o maven para nos ajudar! Então insira o código abaixo dentro do seu arquivo de dependências do maven (pom.xml).

<dependency>
   <groupId>org.bytedeco</groupId>
   <artifactId>javacv-platform</artifactId>
   <version>1.3.1</version>
</dependency>

Após adicionar a dependência do javacv você pode criar um método que recebe bytes do vídeo e te retornará uma imagem em bytes, porém você pode alterar e adapta-lo conforme sua necessidade.

   public byte[] criarThumbnailDoVideo(byte[] bytes) throws IOException {

        // Instanciando e carregando byte para stream
        InputStream inputStream = new ByteArrayInputStream(bytes);

        // Instanciando conversor
        Java2DFrameConverter converter = new Java2DFrameConverter();

        // Instanciando grabber
        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);

        grabber.setImageWidth(720);
        grabber.setImageHeight(400);

        System.out.println(grabber.getImageHeight());
        System.out.println(grabber.getImageWidth());

        //grabber.setFormat("rawvideo");
        //grabber.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        //grabber.setOption("pixel_format", "yuv420p");
        grabber.start();

        Frame frame = grabber.grabImage();

        BufferedImage grabbedImage = converter.convert(frame);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ImageIO.write(grabbedImage, "jpg", byteArrayOutputStream);
        byteArrayOutputStream.flush();
        byte[] imageInByte = byteArrayOutputStream.toByteArray();
        byteArrayOutputStream.close();

        return imageInByte;

    }

Is Working?

Bom, chegamos ao fim desse tutorial, espero que essa dica tenha contribuído para seu conhecimento, caso tenha alguma dúvida ou até mesmo queira deixar um feedback, e que é muito importante para nós, utilize o formulário de comentários abaixo.