当前位置: 首页 > 知识库问答 >
问题:

如何在ARCore[Android Studio]中从session.update()获取位图

王成化
2023-03-14

我正在尝试从我与ARCore的ARSession的当前帧中获取位图。但它总是等于空。我已经在网上搜索了好一阵子,但不能弄清楚我做错了什么。

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){

}

我正在从我的GLSurfaceViewOnDrawFrame中获取mFrame,我使用它来显示相机图像。除了我的位图等于空之外,所有的工作都很好。

我正在使用一个按钮,这样就只使用了一个帧,如下所示:

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();
    }
});

captureDimagebufferbytes都不等于NULL。

mframe.acquirecameraimage()可能有问题吗?

多谢

共有1个答案

段干昊然
2023-03-14

mFrame.AcquireCameraimage()可能有问题吗?

否,mframe.acquirecameraimage()按预期工作。

但它总是等于null

位图将始终等于null,因为位图工厂不理解传递给它的图像数据。

方法mFrame.AcquireCameraimage()使用类型为Image的对象进行响应,该对象为YUV格式或YCbCr。这些类型的图像有3个平面,这在这里得到了很好的解释。这些平面中包含的字节数组可以由本机代码中的CPU/GPU直接读取。BitmapFactory无法读取此类型的数据。因此,您需要将此YUV图像转换为其他图像。

为此,您需要使用YUVIMAGE类创建YUV的实例&然后使用compressoJPEG方法将其转换为JPEG。一旦您从这里获得了byteArray,您就可以简单地执行上面所做的操作。使用BitmapFactory将其转换为位图并将其添加到您的ImageView中。

注:YUV有3架飞机。从所有平面创建单个bytearray&然后将其传递给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)

那只是个粗略的代码。也许还有改进的余地。也请参阅此处。

 类似资料:
  • 问题内容: 如何从Uri获取Bitmap对象(如果我成功将其存储在 以在应用程序中使用它? 有谁知道如何实现这一目标? 问题答案: 这是正确的方法: 如果您需要加载非常大的图像,则以下代码会将其加载到图块中(避免大内存分配):

  • 我正在尝试建立一个简单的“飞鸟”游戏,我需要鸟的图像倾斜,上升时指向上方,反之亦然。然而,当旋转我的图像时,它会在稍微下降或轻触屏幕后部分或完全从屏幕上消失。谁能告诉我怎么解决这个问题吗?

  • 问题内容: 如果我有一个字节,该方法将如何在某个位置取回一个位? 这是我所知道的,我认为它不起作用。 我要从中检索信息的字节的名称在哪里。 问题答案: 按位置向右移动ID将使#position位在数字中最靠右的位置。将其与按位与1结合将告诉您是否设置了该位。

  • 问题内容: 我在使用android定位系统的NETWORK提供程序获取当前位置坐标时遇到麻烦。 已经阅读了很多教程,并为我的项目实现了4到5个现有的类,所有这些类都给了我最后的坐标,而不是当前的坐标。 我很确定这个问题是我遗漏的根本问题,但是我无法理解到底是什么。 我现在正在使用的代码: 这是我的主要活动 这是我用于跟踪的课程: 这是我的AndroidManifest.xml 实际上,GPS定位工

  • 在recyclerView中获取已点击项目的位置,我在recyclerView中创建cardview和链接 我想获取位置,将开关盒设置为每个卡视图的意向活动 当我点击card view I时,他会打开另一个页面,当你点击card view 2时,他会打开另一个页面。 看看我的密码 在recyclerView中获取已点击项目的位置,我在recyclerView中创建cardview和链接 我想获取位

  • 我使用组块来标记数据,并从文本中获取位置。最初,我尝试从next中提取名词短语,当我们使用名词短语名称(也被称为名词短语)时,它无法使用。然后我转移到核心nlp的位置,我试着运行下面的代码 InputStream inputStreamTokenizer=new FileInputStream("文本文档中的D:\project\关系提取\Libraray\解析/en-token.bin");To