Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Taking screenshot of Android OpenGL

Tags:

I'm trying to take a screenshot of Android OpenGL.

The code I found is as follows:

nt size = width * height;
    ByteBuffer buf = ByteBuffer.allocateDirect(size * 4);
    buf.order(ByteOrder.nativeOrder());
    glContext.glReadPixels(0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, buf);
    int data[] = new int[size];
    buf.asIntBuffer().get(data);
    buf = null;
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
    bitmap.setPixels(data, size-width, -width, 0, 0, width, height);
    data = null;

    short sdata[] = new short[size];
    ShortBuffer sbuf = ShortBuffer.wrap(sdata);
    bitmap.copyPixelsToBuffer(sbuf);
    for (int i = 0; i < size; ++i) {
        //BGR-565 to RGB-565
        short v = sdata[i];
        sdata[i] = (short) (((v&0x1f) << 11) | (v&0x7e0) | ((v&0xf800) >> 11));
    }
    sbuf.rewind();
    bitmap.copyPixelsFromBuffer(sbuf);

    try {
        FileOutputStream fos = new FileOutputStream("/sdcard/screeshot.png");
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
    } catch (Exception e) {
        // handle
    }

I tried also a code from that site link text

In each case the result is a png file which is completely black. I found there is some problem with glReadPixels method but I don't know how to bypass it.

like image 512
Gordon Avatar asked Jul 22 '10 16:07

Gordon


People also ask

Can I use OpenGL on Android?

The basics. Android supports OpenGL both through its framework API and the Native Development Kit (NDK).

What is OpenGL traces in Android?

Tracer is a tool for analyzing OpenGL for Embedded Systems (ES) code in your Android application. The tool allows you to capture OpenGL ES commands and frame by frame images to help you understand how your graphics commands are being executed.


1 Answers

Sorry for the late response...

In order to perform a correct screenshot You have to put into Your onDrawFrame(GL10 gl) handler the following code:

if(screenshot){                     
                int screenshotSize = width * height;
                ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
                bb.order(ByteOrder.nativeOrder());
                gl.glReadPixels(0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, bb);
                int pixelsBuffer[] = new int[screenshotSize];
                bb.asIntBuffer().get(pixelsBuffer);
                bb = null;
                Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
                bitmap.setPixels(pixelsBuffer, screenshotSize-width, -width, 0, 0, width, height);
                pixelsBuffer = null;

                short sBuffer[] = new short[screenshotSize];
                ShortBuffer sb = ShortBuffer.wrap(sBuffer);
                bitmap.copyPixelsToBuffer(sb);

                //Making created bitmap (from OpenGL points) compatible with Android bitmap
                for (int i = 0; i < screenshotSize; ++i) {                  
                    short v = sBuffer[i];
                    sBuffer[i] = (short) (((v&0x1f) << 11) | (v&0x7e0) | ((v&0xf800) >> 11));
                }
                sb.rewind();
                bitmap.copyPixelsFromBuffer(sb);
                lastScreenshot = bitmap;

                screenshot = false;
            }

The "screenshot" class field is set to true whenever the user presses the button to create a screenshot or at any other circumstances You want. Inside the "if" body You may place any screenshot creating code sample You find in th internet - the most important thing is having the current instance of GL10. For example when You just save the GL10 instance to the class variable and then use it outside the event to create the screenshot You'll end up with the completely blank image. That's why You have to take a screenshot inside the OnDrawFrame event handler where the GL10 instance is the current one. Hope that it helps.

Best regards, Gordon.

like image 88
Gordon Avatar answered Sep 28 '22 11:09

Gordon