5

我是 Android 开发的新手,并且有一项任务是在指定的时间间隔后读取帧缓冲区数据。

我想出了以下代码:

public class mainActivity extends Activity {
    Bitmap mSavedBM;
    private EGL10 egl;
    private EGLDisplay display;
    private EGLConfig config;    
    private EGLSurface surface;
    private EGLContext eglContext;
    private GL11 gl;
    protected int width, height;


 //Called when the activity is first created. 
@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // get the screen width and height
    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);
    int screenWidth = dm.widthPixels;
    int screenHeight = dm.heightPixels; 

    String SCREENSHOT_DIR = "/screenshots";
    initGLFr(); //GlView initialized.
    savePixels( 0, 10, screenWidth, screenHeight, gl); //this gets the screen to the mSavedBM.
    saveBitmap(mSavedBM, SCREENSHOT_DIR, "capturedImage");

    //Now we need to save the bitmap (the screen capture) to some location.
    setContentView(R.layout.main); //This displays the content on the screen

}
private void initGLFr()
{
    egl = (EGL10) EGLContext.getEGL();
    display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    int[] ver = new int[2];
    egl.eglInitialize(display, ver);

    int[] configSpec = {EGL10.EGL_NONE};
    EGLConfig[] configOut = new EGLConfig[1];
    int[] nConfig = new int[1];
    egl.eglChooseConfig(display, configSpec, configOut, 1, nConfig);
    config = configOut[0];
    eglContext = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
    surface = egl.eglCreateWindowSurface(display, config, SurfaceHolder.SURFACE_TYPE_GPU, null);
    egl.eglMakeCurrent(display, surface, surface, eglContext);
    gl = (GL11) eglContext.getGL();
}
public void savePixels(int x, int y, int w, int h, GL10 gl)
{
    if (gl == null)
            return;

     synchronized (this) {
     if (mSavedBM != null) {
     mSavedBM.recycle();
     mSavedBM = null;
     }
     }

    int b[] = new int[w * (y + h)];
    int bt[] = new int[w * h];
    IntBuffer ib = IntBuffer.wrap(b);
    ib.position(0);
    gl.glReadPixels(x, 0, w, y + h, GL10.GL_RGBA,GL10.GL_UNSIGNED_BYTE,ib);

    for (int i = 0, k = 0; i < h; i++, k++)
    {
        //OpenGLbitmap is incompatible with Android bitmap
        //and so, some corrections need to be done.
            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 - k - 1) * w + j] = pix1;
            }
    }

    Bitmap sb = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
    synchronized (this)
    {
        mSavedBM = sb;
    }
} 

static String saveBitmap(Bitmap bitmap, String dir, String baseName) {
    try {
        File sdcard = Environment.getExternalStorageDirectory();
        File pictureDir = new File(sdcard, dir);
        pictureDir.mkdirs();
        File f = null;
        for (int i = 1; i < 200; ++i) {
            String name = baseName + i + ".png";
            f = new File(pictureDir, name);
            if (!f.exists()) {
                break;
            }
        }
        if (!f.exists()) {
            String name = f.getAbsolutePath();
            FileOutputStream fos = new FileOutputStream(name);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
            return name;
        }
    } catch (Exception e) {

    } finally {

        //if (fos != null) {
         //   fos.close();
       // }

    }
    return null;
}

}

此外,如果有人可以指导我更好地读取帧缓冲区,那就太好了。我正在使用Android 2.2 和API 级别8 的虚拟设备。我经历了许多以前的讨论,发现我们无法直接通过“/dev/graphics/fb0”读取帧缓冲区。

(编辑:重新格式化第一行代码)

4

1 回答 1

2

problem solved, regarding the execution of the above code. But still I could not read the frame buffer data.

I have researched in depth the internals and traced all the previous claims about accessing framebuffer on older versions of Android pre 1.5.

The porting on Android pre 1.5 does have posts on accessing framebuffer directly through /dev/fb0. This does not work for later versions and the Android Development team has no plans as mentioned by them in android google groups.

I hope this helps a lot of people spending a lot of their time to figure out a way.

regards, Ali

于 2010-06-09T11:37:56.317 回答