ImageReaderからBitmapを取り出したい

投稿者: Anonymous

android.media.ImageReaderクラスを使ってSurfaceに送った結果からBitmapを取り出したいのですが、OnImageAvailableListenerのコールバックでどのようにしたらBitmapが作成できるのでしょうか?
ImageReader.acquireLatestImage()で取得できるImageのフォーマットはJPEGです。

ImageReader.OnImageAvailableListener onImageAvailableListener =
  new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader reader) {
      // Bitmap bitmap = doSomethingWith(reader);
    }
};

ちなみにcamera2 APIを使った静止画撮影での用途を想定しています。

解決

ちょっとドキュメント読んだだけでなので自信ないですが、コードで書き下すと以下の様な手順になりそうです。

Image image = reader.acquireLatestImage();
Plane plane = image.getPlanes()[0];
ByteBuffer buf = plane.getBuffer();
byte[] b = buf.array();
int off = buf.arrayOffset();
Bitmap bitmap = BitmapFactory.decodeByteArray(b, off, b.length - off);

ドキュメントを読み解くと、大まかな流れとしては以下のとおりになってるように見受けられました。

  1. Image から Plane を取り出して
  2. Plane から ByteBuffer を取り出して
  3. ByteBuffer の中身を BitmapFactory に食わせる

なお BitmapFactory を使うということは Image#getFormat の説明のJPEGの箇所に書いてあったのを参考にしました。

もしかしたら ByteBuffer#array が失敗するかもしれませんが、その場合は ByteBuffer#get(byte[]) を使って、以下のよう byte[] を取り出し、BitmapFactoryに渡せそうです。

byte[] b = new byte[buf.remaining()];
buf.get(b);
BitmapFactory.decodeByteArray(b, 0, b.length);

以上、外していたらごめんなさい。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *