java - 如何在 ARCore [Android Studio] 中从 session.update() 获取位图
问题描述
我正在尝试使用 ARCore 从我的 ARSession 的当前帧中获取位图。但它始终等于 null。我已经在网上搜索了很长一段时间,但无法弄清楚我做错了什么。
try {
capturedImage = mFrame.acquireCameraImage();
ByteBuffer buffer = capturedImage.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length,null);
if (bitmap == null)
Log.e(TAG,"Bitmap was NOT initialized!");
} catch(Exception e){
}
我是mFrame
从onDrawFrame
我GLSurfaceView
用来显示相机图像的。一切正常,除了我的位图等于空。
我使用的是 Button,因此只使用了一个 Frame,如下所示:
scanButton = (Button) findViewById(R.id.scanButton);
scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
checkbox = false;
if (capturedImage!=null) capturedImage.close();
BitmapMethod();
}
});
capturedImage
,buffer
并且bytes
全部不等于 null。
可能有什么问题mFrame.acquireCameraImage()
吗?
非常感谢
解决方案
mFrame.acquireCameraImage() 可能有问题吗?
不,mFrame.acquireCameraImage()
按预期工作。
但它总是等于 null
由于位图工厂不理解传递给它的图像数据,因此位图将始终等于 null。
该方法以 YUV 格式或 YCbCrmFrame.acquireCameraImage()
类型的对象进行响应。Image
这些类型的图像有 3 个平面,这里很好地解释了这些平面。这些平面中包含的内容可以由 CPU/GPU 在代码ByteArray
中直接读取。无法读取此类数据。因此,您需要将此 YUV 图像转换为其他图像。native
BitmapFactory
为此,您需要使用YuvImage
类来创建 YUV 的实例,然后使用该compressToJpeg
方法将其转换为 JPEG。一旦你得到了 byteArray,你就可以简单地做你在上面做的事情。用于BitmapFactory
将其转换为位图并将其添加到您的ImageView
.
注意:YUV 有 3 个平面。从所有平面创建一个字节数组,然后将其传递给 YUV 构造函数。虽然没有详细说明,但它应该看起来类似于:
//The camera image received is in YUV YCbCr Format. Get buffers for each of the planes and use them to create a new bytearray defined by the size of all three buffers combined
val cameraPlaneY = cameraImage.planes[0].buffer
val cameraPlaneU = cameraImage.planes[1].buffer
val cameraPlaneV = cameraImage.planes[2].buffer
//Use the buffers to create a new byteArray that
val compositeByteArray = ByteArray(cameraPlaneY.capacity() + cameraPlaneU.capacity() + cameraPlaneV.capacity())
cameraPlaneY.get(compositeByteArray, 0, cameraPlaneY.capacity())
cameraPlaneU.get(compositeByteArray, cameraPlaneY.capacity(), cameraPlaneU.capacity())
cameraPlaneV.get(compositeByteArray, cameraPlaneY.capacity() + cameraPlaneU.capacity(), cameraPlaneV.capacity())
val baOutputStream = ByteArrayOutputStream()
val yuvImage: YuvImage = YuvImage(compositeByteArray, ImageFormat.NV21, cameraImage.width, cameraImage.height, null)
yuvImage.compressToJpeg(Rect(0, 0, cameraImage.width, cameraImage.height), 75, baOutputStream)
val byteForBitmap = baOutputStream.toByteArray()
val bitmap = BitmapFactory.decodeByteArray(byteForBitmap, 0, byteForBitmap.size)
imageView.setImageBitmap(bitmap)
这只是一个粗略的代码。它也许有改进的余地。另请参阅此处。
推荐阅读
- java-bytecode-asm - 使用 ASM 重命名类时内部类的 NoClassDefFoundError
- mysql - 如何从两个表中检索数据?
- r - 在 ggplot R 中使用和调整 bbc 风格主题
- c++ - QDataStream 和 QByteArray wirh ByteOrder
- java - 为什么不接受 super(id)?
- pine-script - 松树脚本:不能使用变量作为输入的defval?
- react-native - React Native RazorPay android Undefined|Undefined 在点击支付按钮上显示
- python - 如果我们使用多个断言第一个断言失败,我应该如何继续我的脚本?
- reactjs - React 应用程序在 localhost 上运行,但在 github 或 heroku 上部署时出错。部署时没有错误
- c# - 键入时 Visual Studio 未突出显示 C# 中的建议