You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FFmpegFrameGrabber读取的MP4帧如何转换为Google ML Kit的InputImage

解决方案

方案1:跳过BufferedImage,直接转换Frame为InputImage(实现简单)

Android平台确实不支持Java AWT的BufferedImage类,你可以直接通过JavaCV自带的AndroidFrameConverter把FFmpegFrameGrabber读取到的Frame直接转成Android原生Bitmap,再生成ML Kit要求的InputImage,步骤如下:

  1. 初始化帧抓取器时指定像素格式,降低转码开销
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(path);
// 指定输出RGBA格式,方便后续转Bitmap
frameGrabber.setPixelFormat(AV_PIX_FMT_RGBA);
frameGrabber.start();
Frame frame;
try {
    // 仅抓取图像帧,跳过音频帧提升效率
    frame = frameGrabber.grabImage();
} catch (Exception e) {
    e.printStackTrace();
}
  1. 转换Frame为Bitmap
// 转换器全局复用即可,不要每次处理帧都创建,减少GC
AndroidFrameConverter converter = new AndroidFrameConverter();
Bitmap bitmap = converter.convert(frame);
  1. 生成InputImage
// 第二个参数为视频帧的旋转角度,根据视频元数据的旋转信息填写,无旋转默认传0
InputImage inputImage = InputImage.fromBitmap(bitmap, 0);

注意:处理完成后及时调用bitmap.recycle()回收内存,避免OOM。

方案2:更优实现(性能更高,适合高帧率/长视频处理)

ML Kit对YUV格式的处理效率远高于RGB格式,你可以直接输出NV21格式的帧数据,跳过Bitmap创建环节,整体处理速度可提升30%以上:

  1. 初始化帧抓取器时指定输出NV21格式
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(path);
frameGrabber.setPixelFormat(AV_PIX_FMT_NV21);
frameGrabber.start();
  1. 直接读取帧字节数组生成InputImage
Frame frame = frameGrabber.grabImage();
byte[] nv21Data = new byte[frame.image[0].limit()];
frame.image[0].get(nv21Data);

InputImage inputImage = InputImage.fromByteArray(
    nv21Data,
    frameGrabber.getImageWidth(),
    frameGrabber.getImageHeight(),
    0, // 旋转角度
    InputImage.IMAGE_FORMAT_NV21
);

内容的提问来源于stack exchange,提问作者Arun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:36:01