Estoy tratando de tomar una captura de pantalla de Android OpenGL.

El código que he encontrado es la 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
}

He intentado también un código de ese sitio
enlace de texto

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

InformationsquelleAutor Gordon | 2010-07-22

3 Comentarios

  1. 23

    Lo siento por la respuesta tardía…

    Con el fin de realizar una correcta captura de pantalla tienes Que poner en Tu onDrawFrame(GL10 gl) controlador 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;
    }

    La «captura de pantalla» de la clase de campo se establece en true cuando el usuario presiona el botón para crear una captura de pantalla
    o en cualquier otra circunstancia Que desee. En el interior del «si» cuerpo puede poner alguna captura de pantalla de la creación de código de ejemplo que Usted encuentra en el internet – la cosa más importante es tener la instancia actual de GL10. Por ejemplo, cuando Usted acaba de guardar el GL10 ejemplo, a la variable de clase y, a continuación, utilizarlo fuera del evento para crear la imagen de Que va a terminar con la imagen en blanco. Es por eso que Usted tiene que tomar una captura de pantalla dentro de la OnDrawFrame controlador de eventos donde la GL10 ejemplo es la actual.
    Espero que esto ayude.

    Saludos, Gordon.

    • me estoy poniendo erroneal colores con esta solución, por ejemplo, los colores amarillos están pintadas de colores como el azul…¿? cómo resolverlo por favor?
    • Gordon ¿Cómo se puede inicializar gl ?
  2. 10

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

    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;
    }
    • Muchas gracias, me salvó mucho cariño …. 😛 @Spartarel
    • He utilizado el método y funciona bien si puedo guardar el mapa de bits afte 1 seg de hacer captura de pantalla el valor true. si yo ni siquiera esperar a 500 milisec guarda una mala imagen a color… es que la operación que lleva más tiempo? @Spatarel
    • ¿alguna vez encontrar una solución a ese problema?
  3. 2

    Tengo!

    Mi error fue que yo estaba recordando GL contexto en el que la variable de clase. Con el fin de tomar una captura de pantalla que tengo que usar el contexto de gl pasa a la OnDraw en la clase que implementa GLSurfaceView.Representador de la interfaz. Yo simplemente uso mi código en la cláusula «si» y todo funciona como se espera. Espero que el comentario iba a ayudar a nadie.

    Saludos
    Gordon

Dejar respuesta

Please enter your comment!
Please enter your name here