BitmapFactory.getByteArray 仅当字节数组来自存储时才有效
BitmapFactory.getByteArray only works if the byte array come from storage
我正在尝试创建一个程序来直接处理来自 Camera2 预览的图像,但在实际处理传入图像时我一直 运行 遇到问题。
在我的 OnImageAvailableListener.onImageAvailable() 回调中,我得到了一个 ImageReader
对象,我从中 acquireNextImage() 并将该 Image 对象传递到我的辅助函数中。从那里,我将它转换成一个字节数组,并尝试进行处理。相反,每次我到达将其转换为 Bitmap
的部分时,BitmapFactory.getByteArray
returns null,即使字节数组是格式正确的 JPEG。
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.get(bytes)
之后,buffer.remaining()
将 return 0,因为您刚刚读取了整个 ByteBuffer。 remaining()
告诉您当前位置和缓冲区限制之间还剩下多少字节,然后调用 get()
将位置向前移动读取的字节数。
因此,当您执行 decodeByteArray(bytes,0, buffer.remaining(), 0)
时,您实际上并没有解码任何字节。
如果您尝试 decodeByteArray(bytes, 0, bytes.length, 0)
,是否有效?
我正在尝试创建一个程序来直接处理来自 Camera2 预览的图像,但在实际处理传入图像时我一直 运行 遇到问题。
在我的 OnImageAvailableListener.onImageAvailable() 回调中,我得到了一个 ImageReader
对象,我从中 acquireNextImage() 并将该 Image 对象传递到我的辅助函数中。从那里,我将它转换成一个字节数组,并尝试进行处理。相反,每次我到达将其转换为 Bitmap
的部分时,BitmapFactory.getByteArray
returns null,即使字节数组是格式正确的 JPEG。
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.get(bytes)
之后,buffer.remaining()
将 return 0,因为您刚刚读取了整个 ByteBuffer。 remaining()
告诉您当前位置和缓冲区限制之间还剩下多少字节,然后调用 get()
将位置向前移动读取的字节数。
因此,当您执行 decodeByteArray(bytes,0, buffer.remaining(), 0)
时,您实际上并没有解码任何字节。
如果您尝试 decodeByteArray(bytes, 0, bytes.length, 0)
,是否有效?