找到正确的上下文以使用glReadPixels()获取屏幕截图

时间:2013-03-27 09:10:33

标签: java android opengl-es screenshot glreadpixels

我正试图通过glReadPixels()直接从帧缓冲区读取,这样我就可以从屏幕上的任何内容中截取屏幕截图。
我没有使用GUI,而是每次触摸屏幕时都应该打印屏幕的原始内容(这对于开始就足够了)。

我现在无法为gl.glReadPixels()函数获取正确的上下文。
因为我认为我现在得到的上下文与屏幕上的内容无关。

当我运行应用程序时,它会输出一个libEGL错误,上面写着

  

调用没有当前上下文的OpenGL ES API(每个记录一次   螺纹)

然后我的数组充满了零。

要隐藏我的应用程序,我在清单中使用以下行。

android:theme="@android:style/Theme.Translucent.NoTitleBar" 

以下是代码:

public class ScreenshotActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {   
                savePixels();
        }
        return true;
    }


    EGL10 egl = (EGL10) EGLContext.getEGL();
    GL10 gl = (GL10) egl.eglGetCurrentContext().getGL();

    public void savePixels() {
         w= getWidth(this);
         h= getHeight(this);
         int b[] = new int[w * h];
         int bt[] = new int[w * h];
         IntBuffer ib = IntBuffer.wrap(b);
         ib.position(0);

         gl.glReadPixels(0, 0, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);


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

             Log.w("debug", Arrays.toString(bt));
             moveTaskToBack(true);
    }
}

非常感谢帮助:)

3 个答案:

答案 0 :(得分:1)

有人可以停止尝试滥用OpenGL来拍摄屏幕截图吗?如果你想捕获执行glReadPixels调用的程序的渲染输出,那很好,但是一旦其他程序成为目标像素源,它就变得非常不可靠。

获取全屏截图的唯一可靠方法是直接从GPU视频缓冲内存中读取。 Android基于Linux,Linux为此提供了fbdev设备。由于使用所有这些ioctl有点麻烦,应该使用一些测试库。有一个Android库,提供了一个用于截取屏幕截图的专用API:http://code.google.com/p/android-screenshot-library/wiki/DeveloperGuide

答案 1 :(得分:0)

mGLSurfaceView.queueEvent(new Runnable() {
  public void run() {
    savePixels();
  }
});

您必须将mGLSurfaceView更改为SurfaceView实例。

答案 2 :(得分:0)

最后发现了一个开源程序,它没有使用/ dev / graphics / fb0来捕获帧缓冲区。

fb2png包括一个C程序和一个python脚本,它们都运行良好。