bytedeco/javacv

How to draw transparent frames in video

Open

#1,923 创建于 2022年11月3日

在 GitHub 查看
 (3 评论) (0 反应) (0 负责人)Java (1,583 fork)batch import
help wantedquestion

仓库指标

Star
 (6,985 star)
PR 合并指标
 (30 天内没有已合并 PR)

描述

Hi, in code below, input a background image and a video with alpha channel. I want to give every frame a backgound image. but, every frame's transparent zone is black color, not transparent i except. please give me some help about my purpose

in the code, 1/2/3 code part is set to ABGR.

I guess:

  1. tell the grabber to convert the origin pixel format to ABGR.
  2. tell the recorder the image in the frame's pixel format is ABGR.
  3. tell the graphics obj, to create a ABGR format's canvas, and all future drawed image's format is ABGR.

Is my guess correct? please give me some help about my purpose, thank you.

`

FFmpegLogCallback.set();

frameGrabber = new FFmpegFrameGrabber(srcfile); frameGrabber.setPixelFormat(avutil.AV_PIX_FMT_ABGR); // 1 set to ABGR

Frame captured_frame = null;

try { frameGrabber.start();

  recorder = new FFmpegFrameRecorder(destfile, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
  recorder.setInterleaved(true);
  recorder.setVideoOption("tune","zerolatency");
  recorder.setVideoOption("preset", "ultrafast");
  recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
  recorder.setFormat("flv");

  recorder.setFrameRate(frameGrabber.getFrameRate());
  recorder.setVideoBitrate(frameGrabber.getVideoBitrate());

  recorder.setAudioBitrate(192000);
  recorder.setAudioOptions(frameGrabber.getAudioOptions());
  recorder.setAudioQuality(0);
  recorder.setSampleRate(44100);
  recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
  recorder.start();

  frameGrabber.setTimestamp(0);

  while (true) {
      try {
          captured_frame = frameGrabber.grabFrame();

          if (captured_frame == null) {
              System.out.println("!!! Failed cvQueryFrame");
              break;
          }

          if(captured_frame.type == Frame.Type.VIDEO){
              captured_frame = MixFrameDraw(captured_frame); 
          }else{
              //System.out.println("audio frame");
          }

          recorder.record(captured_frame, AV_PIX_FMT_ABGR);            // 2 is set ABGR
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

}

public static Frame MixFrameDraw(Frame frame){ BufferedImage imgFrame = frameConverter.getBufferedImage(frame);

  BufferedImage res = new BufferedImage(bufferImgBg.getWidth(), bufferImgBg.getHeight(), BufferedImage.TYPE_INT_ABGR);  // 3 set to ABGR

  Graphics graphics = res.getGraphics();
  graphics.drawImage(bufferImgBg, 0, 0, null);

  //  video frame is smaller than background image, draw it a x,y offset
  // I except that here will draw a tranparent image, because video has alpha channel, but the transparent zone is black color 
  graphics.drawImage(imgFrame, 100, 100, null);   

  return frameConverter.getFrame(res);

}

`

贡献者指南