繁体   English   中英

使用OpenGL将每个相机帧处理为位图

[英]Process every camera frame as Bitmap with OpenGL

我有一个应用程序,我想在其中处理相机中的每个给定帧,以做一些ARCore的工作。 因此,我有一个实现GLSurfaceView.Renderer的类,并且在该类中有onDrawFrame(GL10 gl)方法。 在这种方法中,我想使用Android位图,因此我调用以下代码从当前帧中获取位图:

private Bitmap getTargetImageBitmapOpenGL(int cx, int cy, int w, int h) {
    try {

      if (currentTargetImageBitmap == null) {
        currentTargetImageBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

        byteBuffer = ByteBuffer.allocateDirect(w * h * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
      }

      // cy = height - cy;

      if ((cx + w / 2) > width) {
        Log.e(TAG, "TargetImage CenterPoint invalid A: " + cx + " " + cy);
        cx = width - w / 2;
      }

      if ((cx - w / 2) < 0) {
        Log.e(TAG, "TargetImage CenterPoint invalid B: " + cx + " " + cy);
        cx = w / 2;
      }

      if ((cy + h / 2) > height) {
        Log.e(TAG, "TargetImage CenterPoint invalid C: " + cx + " " + cy);
        cy = height - h / 2;
      }

      if ((cy - h / 2) < 0) {
        Log.e(TAG, "TargetImage CenterPoint invalid D: " + cx + " " + cy);
        cy = h / 2;
      }

      int x = cx - w / 2;
      int y = cy - h / 2;

      GLES20.glReadPixels(x, y, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,
          byteBuffer);

      IntBuffer currentTargetImagebuffer = byteBuffer.asIntBuffer();

      currentTargetImagebuffer.rewind();
      currentTargetImageBitmap.copyPixelsFromBuffer(currentTargetImagebuffer);

      return currentTargetImageBitmap;

    } catch (Exception e) {
      e.printStackTrace();
    }

    return null;
  }

该方法大约需要90毫秒,这对于实时处理每个传入帧绝对太慢,这是我需要做的,因为onDrawFrame(GL10 gl)方法还将此帧绘制到曲面视图。 知道为什么这么慢吗? 如果我只能读取其他每一帧的像素,但将每一帧绘制到我的SurfaceView,也就足够了。 我试图在AsyncTask.execute()调用显示的方法,但是另一个线程无法通过GLES20.glReadPixels()方法读取,因为它不是GL线程。

许多现代GPU可以本地解码YUV。 问题是如何使YUV表面进入OpenGL ES,因为这通常不是Open GL ES要做的。 大多数操作系统(包括Android)允许您通过EGL_image_external扩展将外部表面直接导入OpenGL ES,并且可以使用自动颜色转换将这些外部表面标记为YUV。

更好的是,所有这些都是零复制的。 相机缓冲区可以直接由GPU导入和访问。

此Android导入机制是通过SurfaceTexture类进行的,必要的用法在此处进行了描述: https : SurfaceTexture

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM