2015-01-14 76 views
2

在我的应用程序中,用户有时必须有机会拍屏幕截图。为了提供它,我使用下面显示的方法(实际上OpenGL只是绘制成位图)是否有替代OpenGL ES的慢速屏幕截图?

private boolean drawToBmp() 
    throws OutOfMemoryError { 

    int b[]=new int[(int) (w*h)]; 
    int bt[]=new int[(int) (w*h)]; 
    IntBuffer buffer=IntBuffer.wrap(b); 
    buffer.position(0); 

    try { 
     GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); 
     for (int i = 0; i < h; i++) 
      for (int j = 0; j < w; j++) { 
       int pix = b[i * w + j]; 
       int pb = (pix >> 16) & 0xff; 
       int pr = (pix << 16) & 0x00ff0000; 
       int pix1 = (pix & 0xff00ff00) | pr | pb; 
       bt[(h - i - 1) * w + j] = pix1; 
      } 
    } 
    catch (GLException e) { 
     return false; 
    } 
    scrShot = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888); 
    return true; 
} 

不幸的是,它的工作速度太慢。有没有更快(也许更干净)的方法来提供屏幕截图(当然,没有任何用户的根模式)?

+0

将for循环移动到另一个线程 –

+0

我的应用程序上面描述的方法实际上在其自己的线程中工作。但是主线程必须等到位图被采用,因为它在下一个时刻被使用。 –

回答

0

如果您的图像是完全不透明的(即,α-始终为255),有一招,以避免对循环:

  • 创建的缓冲区是至少一个字节不是以保持所需要的更大图像
  • 传递用一个字节的缓冲器偏移,以glReadPixels
  • 使第一像素的α值设定为255(即缓冲器的第一个字节,其在调用glReadPixels时跳过)

另外,看看这个: https://vec.io/posts/faster-alternatives-to-glreadpixels-and-glteximage2d-in-opengl-es

+0

这很有用。谢谢。 –