0

我正在尝试通过 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);
    }
}

高度赞赏帮助:)

4

3 回答 3

1

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

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

于 2013-03-27T10:44:18.947 回答
0

终于找到了一个开源程序,它没有使用 /dev/graphics/fb0 来捕获帧缓冲区。

fb2png包含一个 C 程序和一个 python 脚本,它们都可以完美运行。

于 2013-04-19T12:28:24.050 回答
0
mGLSurfaceView.queueEvent(new Runnable() {
  public void run() {
    savePixels();
  }
});

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

于 2013-03-27T09:35:20.690 回答