2016-09-09 16 views
0

Camera2プレビューから直接画像を処理するプログラムを作成しようとしていますが、実際に着信画像を処理する際に問題が発生し続けます。私OnImageAvailableListener.onImageAvailable()コールバックでBitmapFactory.getByteArrayは、バイト配列がストレージから来た場合にのみ動作します

、私はImageReaderオブジェクトを取得し、よりI acquireNextImage()と私のヘルパー関数にそのImageオブジェクトを渡しています。そこからバイト配列に変換し、処理を試みます。代わりに、私がBitmapに変換する部分に行くたびに、BitmapFactory.getByteArrayは、バイト配列が適切にフォーマットされたJPEGであっても、nullを返します。

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener 
     = new ImageReader.OnImageAvailableListener() { 
    @Override 
    public void onImageAvailable(ImageReader imageReader) { 
     Image image = imageReader.acquireNextImage(); 
     ProcessBarcode(image); 
     image.close(); 
    } 
}; 

private void ProcessBarcode(Image image) { 
    ByteBuffer buffer = image.getPlanes()[0].getBuffer(); 
    int bufferSize = buffer.remaining(); 
    byte[] bytes = new byte[bufferSize]; 
    buffer.get(bytes); 

    FileOutputStream output = null; 
    try { 
     output = new FileOutputStream(mFile); 
     output.write(bytes); 
     output.close(); 
    } catch (IOException e) { 
     // Do something clever 
    } 

    // This call FAILS 
    //Bitmap b = BitmapFactory.decodeByteArray(bytes, 0, buffer.remaining(), o); 

    // But this call WORKS? 
    Bitmap b = BitmapFactory.decodeFile(mFile.getAbsolutePath()); 

    detector = new BarcodeDetector.Builder(getActivity()) 
      .setBarcodeFormats(Barcode.EAN_13 | Barcode.ISBN) 
      .build(); 

    if (b != null) { 
     Frame isbnFrame = new Frame.Builder().setBitmap(b).build(); 
     SparseArray<Barcode> barcodes = detector.detect(isbnFrame); 

     if (barcodes.size() != 0) { 
      Log.d("Barcode decoded: ",barcodes.valueAt(0).displayValue); 
     } 
     else { 
      Log.d(TAG, "No barcode detected"); 
     } 
    } 
    else { 
     Log.d(TAG, "No bitmap detected"); 
    } 
} 

ImageReaderが同じように設定されています。基本的に私は何を参照してください、私は最初の内部メモリに保存せずに直接バイト配列を使用している場合、カメラのプレビューが迅速かつてきぱきであるということである

mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 2); 
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); 

Bitmapは常にnullなので、実際に処理を行っているわけではありません。バイト配列をメモリに保存すると、2〜3fpsが得られるかもしれませんが、処理は私が意図している通りに機能します。

答えて

0

buffer.get(bytes)を呼び出した後、buffer.remaining()は、ByteBuffer全体を読み取るだけなので、0を返します。 remaining()は、現在の位置とバッファの限界の間に何バイトが残っているかを示し、get()を呼び出すと、読み取られたバイト数だけ前方に移動します。

したがって、decodeByteArray(bytes,0, buffer.remaining(), 0)を実行すると、実際にはバイトはデコードされません。

decodeByteArray(bytes, 0, bytes.length, 0)を試しても問題ありませんか?

+0

ありがとうございました! buffer.remaining()の代わりに 'bytes.length'を直接取得することで問題は解決しました。私はまだ恐ろしいスキャンレートを持っていますが、私はそれが画像をキャプチャすることに関連するものではなく、バーコードをデコードすることの問題だと思います。 – Jared

+0

フレームレートを高くしたい場合は、JPEGをキャプチャしないでください。通常は遅いです(一般的に1〜3フレーム、通常は最高10フレーム)。代わりにImageFormat.YUV_420_888を使用してください。プレビュー解像度では少なくとも30fpsで動作することが保証されています。また、画像ごとに新しいバーコードスキャナを作成することも避けてください。私はあなたが1つを何度も再利用できると思います。 –

+0

私はこのトピックに触れた別のスレッドを見つけましたが(私の明白な間違いではありませんが)、YUV_420_888フォーマットも提案されています。カメラがまだAFとAEロックを取得していないときにキャプチャされたフレームを除外して、プレビューモードでフレームレートを修正しました。今はすべてのプレビューフレームを表示していますが、カメラで確実にロックされた後でバーコードスキャンを行うだけです。それはほぼリアルタイムに戻ります。 – Jared

関連する問題