Tomando una captura de pantalla de Android OpenGL

Estoy intentando tomar una captura de pantalla de Android OpenGL.

El código que encontré es el siguiente:

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 } 

También he intentado un código de ese texto de enlace de sitio

En cada caso el resultado es un archivo png que es completamente negro. He encontrado que hay algún problema con el método glReadPixels , pero no sé cómo evitarlo.

Lo siento por la respuesta tardía…

Con el fin de realizar una captura de pantalla correcta Usted tiene que poner en su manejador onDrawFrame (GL10 gl) el siguiente código:

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

El campo de la clase "screenshot" se establece en true siempre que el usuario presione el botón para crear una captura de pantalla o en cualquier otra circunstancia que desee. En el interior del "si" el cuerpo Usted puede colocar cualquier captura de pantalla creando código de ejemplo Usted encuentra en el internet – lo más importante es tener la instancia actual de GL10. Por ejemplo, cuando usted acaba de guardar la instancia GL10 a la variable de clase y luego utilizarlo fuera del evento para crear la captura de pantalla que terminará con la imagen completamente en blanco. Es por eso que tienes que tomar una captura de pantalla dentro del controlador de eventos OnDrawFrame donde la instancia GL10 es la actual. Espero que ayude.

Saludos cordiales, Gordon.

Aquí está la manera de hacerlo si desea conservar la calidad (8 bits para cada canal de color: rojo, verde, azul y alfa también):

 if (this.screenshot) { int screenshotSize = this.width * this.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; for (int i = 0; i < screenshotSize; ++i) { // The alpha and green channels' positions are preserved while the red and blue are swapped pixelsBuffer[i] = ((pixelsBuffer[i] & 0xff00ff00)) | ((pixelsBuffer[i] & 0x000000ff) << 16) | ((pixelsBuffer[i] & 0x00ff0000) >> 16); } Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixelsBuffer, screenshotSize-width, -width, 0, 0, width, height); this.screenshot = false; } 

¡Lo tengo!

Mi error fue que estaba recordando el contexto GL en la variable de clase. Para tomar una captura de pantalla, tengo que usar el contexto gl pasado a OnDraw en la clase implementando la interfaz GLSurfaceView.Renderer. Simplemente uso mi código en la cláusula "if" y todo funciona como se esperaba. Espero que esa observación ayude a cualquiera.

Saludos cordiales, Gordon

  • Píxeles de lectura de Android desde GL_TEXTURE_EXTERNAL_OES
  • cómo manejar el botón de nuevo cuando llamamos a facebook o twitter de la clase Fragment?
  • Android OpenGL ES - Todas las extensiones compatibles?
  • OpenGL ES - textura mapa todas las caras de un cubo de 8 vértices?
  • Android: Limpiar correctamente después de OpenGL
  • Programación de juegos Android 2D: ¿usando OpenGL o no?
  • Tutorial para Android OpenGL ES
  • OpenGL ES tutorial para android no parece funcionar
  • ¿Hay una mejor manera de depurar OpenGL que de llamar a glGetError después de cada comando?
  • ¿Cuándo debemos utilizar LAYER_TYPE_HARDWARE
  • Cualquier buen ejemplo para openGLES shader en android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.