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が得られるかもしれませんが、処理は私が意図している通りに機能します。
ありがとうございました! buffer.remaining()の代わりに 'bytes.length'を直接取得することで問題は解決しました。私はまだ恐ろしいスキャンレートを持っていますが、私はそれが画像をキャプチャすることに関連するものではなく、バーコードをデコードすることの問題だと思います。 – Jared
フレームレートを高くしたい場合は、JPEGをキャプチャしないでください。通常は遅いです(一般的に1〜3フレーム、通常は最高10フレーム)。代わりにImageFormat.YUV_420_888を使用してください。プレビュー解像度では少なくとも30fpsで動作することが保証されています。また、画像ごとに新しいバーコードスキャナを作成することも避けてください。私はあなたが1つを何度も再利用できると思います。 –
私はこのトピックに触れた別のスレッドを見つけましたが(私の明白な間違いではありませんが)、YUV_420_888フォーマットも提案されています。カメラがまだAFとAEロックを取得していないときにキャプチャされたフレームを除外して、プレビューモードでフレームレートを修正しました。今はすべてのプレビューフレームを表示していますが、カメラで確実にロックされた後でバーコードスキャンを行うだけです。それはほぼリアルタイムに戻ります。 – Jared