[英]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.