Capture Screen of Glsurfaceview to Bitmap

Capture screen of GLSurfaceView to bitmap

SurfaceView and GLSurfaceView punch holes in their windows to allow their surfaces to be displayed. In other words, they have transparent areas.

So you cannot capture an image by calling GLSurfaceView.getDrawingCache().

If you want to get an image from GLSurfaceView, you should invoke gl.glReadPixels() in GLSurfaceView.onDrawFrame().

I patched createBitmapFromGLSurface method and call it in onDrawFrame().

(The original code might be from skuld's code.)

private Bitmap createBitmapFromGLSurface(int x, int y, int w, int h, GL10 gl)
throws OutOfMemoryError {
int bitmapBuffer[] = new int[w * h];
int bitmapSource[] = new int[w * h];
IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
intBuffer.position(0);

try {
gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
int offset1, offset2;
for (int i = 0; i < h; i++) {
offset1 = i * w;
offset2 = (h - i - 1) * w;
for (int j = 0; j < w; j++) {
int texturePixel = bitmapBuffer[offset1 + j];
int blue = (texturePixel >> 16) & 0xff;
int red = (texturePixel << 16) & 0x00ff0000;
int pixel = (texturePixel & 0xff00ff00) | red | blue;
bitmapSource[offset2 + j] = pixel;
}
}
} catch (GLException e) {
return null;
}

return Bitmap.createBitmap(bitmapSource, w, h, Bitmap.Config.ARGB_8888);
}

how to get output bitmap from GLSurfaceView?

You can read the pixels back with glReadPixels() after you're done rendering, but before eglSwapBuffers() is called. You're using GLSurfaceView, which does the buffer-swap for you when onDrawFrame() returns, so you'll need to do the capture right at the end of onDrawFrame().

You can find an example that saves the current GLES framebuffer to a PNG in Grafika. See the EglSurfaceBase#saveFrame() method (you can ignore the mEglCore test at the top).

[Cocos2d]How to Create bitmap from GlSurfaceView

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

Display black screen while capture screenshot of GLSurfaceView

try this...

private volatile boolean saveFrame;

// called when Capture button is clicked.
public void onClick(View view) {
saveFrame = true;
mEffectView.requestRender();
}

@Override
public void onDrawFrame(GL10 gl) {
if (!mInitialized) {
// Only need to do this once
mEffectContext = EffectContext.createWithCurrentGlContext();
mTexRenderer.init();
loadTextures();
mInitialized = true;
}
if (mCurrentEffect != NONE) {
// if an effect is chosen initialize it and apply it to the texture
initEffect();
applyEffect();
}
renderResult();
if (saveFrame) {
saveBitmap(takeScreenshot(gl));
saveFrame = false;
}
}

private void saveBitmap(Bitmap bitmap) {
try {
FileOutputStream stream = openFileOutput("image.png", MODE_PRIVATE);
bitmap.compress(CompressFormat.PNG, 100, stream);
stream.flush();
stream.close();
Log.i("TAG", "SAVED");
} catch (Exception e) {
Log.e("TAG", e.toString(), e);
}
}

public Bitmap takeScreenshot(GL10 mGL) {
final int mWidth = mEffectView.getWidth();
final int mHeight = mEffectView.getHeight();
IntBuffer ib = IntBuffer.allocate(mWidth * mHeight);
IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight);
mGL.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);

// Convert upside down mirror-reversed image to right-side up normal image.
for (int i = 0; i < mHeight; i++) {
for (int j = 0; j < mWidth; j++) {
ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j));
}
}

Bitmap mBitmap = Bitmap.createBitmap(mWidth, mHeight,Bitmap.Config.ARGB_8888);
mBitmap.copyPixelsFromBuffer(ibt);
return mBitmap;
}


Related Topics



Leave a reply



Submit