4

How can I take screen shot of Glsurfaceview in Cocos2d. I tried with following code using GLsurfaceView

    GlsurfaceView glv=CCDirector.sharedDirector().getOpenGLView();
    glv.setDrawingCacheEnabled(true);
    Bitmap bitmap=glv.getDrawingCache();

but it return transparent image.

Dev.Sinto
  • 6,802
  • 8
  • 36
  • 54

2 Answers2

4

I got answer from this anddev forum question I attached code along with this hope somebody will find this helpful

Please Put this code inside renderer class onDraw Method inside starting.

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

    /*  remember, that OpenGL bitmap is incompatible with 
        Android bitmap and so, some correction need.
     */   
    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;
        }
    }              
    Bitmap sb=Bitmap.createBitmap(bt, w, h, true);
    return sb;
}

public static void SavePNG(int x, int y, int w, int h, String name, GL10 gl)
{
    Bitmap bmp=SavePixels(x,y,w,h,gl);
    try
    {
        FileOutputStream fos=new FileOutputStream("/sdcard/my_app/"+name);
        bmp.compress(CompressFormat.PNG, 100, fos);
        try
        {
            fos.flush();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try
        {
            fos.close();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    catch (FileNotFoundException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }              
}
Dev.Sinto
  • 6,802
  • 8
  • 36
  • 54
  • @kariyachan.. this code this wrong. It gives error at CreateBitmap function. – Noman Dec 16 '11 at 07:31
  • @DroidBot Hi I am trying to make your code work but I am getting error 1282 after the call to glreadpixels... any thoughts? – Amit Raz Oct 20 '13 at 16:49
  • There is no such method (Bitmap.createBitmap(bt, w, h, true);) in Bitmap – Sergey Pekar Apr 28 '15 at 14:25
  • 1
    @DroidBot your method is correct if someone wants to save the whole GLSurfaceView. But what If i only want to save the bitmap portion of the GLSurfaceView? Please have a look at this: http://stackoverflow.com/questions/32601187/how-to-save-bitmap-from-glsurfaceview-only-bitmap-not-whole-texture – Shreyash Mahajan Sep 16 '15 at 07:15
2

Here is solution:

if (MainImageProcessingActivity.capture) {
        int width = MainImageProcessingActivity.w;
        int height = MainImageProcessingActivity.h;
        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);
        MainImageProcessingActivity.captureBmp = bitmap.copy(Bitmap.Config.ARGB_8888,false);
        MainImageProcessingActivity.capture=false;
    }

put the code under onDrawFrame(GL10 gl) method, IT WORKS!

Peter
  • 260
  • 5
  • 3
  • Hi Peter, Thanks for your Code. i used this code in my renderer class and inside onDraw method..Its working fine..... – harikrishnan Jun 07 '13 at 05:54
  • @Peter what if the Image is landscape type in height-width and you are loading it in GLSurfaceView. I guess it is taking whole Device screen to make new bitmap with above code. – Shreyash Mahajan Sep 16 '15 at 13:13
  • try to resolved this issue: http://stackoverflow.com/questions/32601187/how-to-save-bitmap-from-glsurfaceview-only-bitmap-not-whole-texture – Shreyash Mahajan Sep 16 '15 at 13:13