Autore Topic: Catturare in una Bitmap l'output di una SurfaceView  (Letto 1210 volte)

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Catturare in una Bitmap l'output di una SurfaceView
« il: 04 Febbraio 2013, 19:02:09 CET »
0
Sapete come si fa a a stampare l'output di una surface view?
Ho una visualizzazione in opengl che faccio su una SurfaceView mi servirebbe di poter stampare la parte che sto visualizzando in quel dato momento e metterla in una bitmap voi sapete come si fa?
Ho provato in diversi modi ma mi da sempre una bitmap tutta nera con sopra i pulsanti che inserisco nel layout.
Qualcuno sa indirizzarmi?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #1 il: 04 Febbraio 2013, 20:08:08 CET »
0
Una superficie OpenGL non può essere catturata come se fosse una normale View, devi usare la funzione glReadPixels:

http://developer.android.com/reference/android/opengl/GLES20.html#glReadPixels%28int,%20int,%20int,%20int,%20int,%20int,%20java.nio.Buffer%29

La documentazione si trova nel sito ufficiale delle OpenGL-ES:

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glReadPixels.xml

tieni conto che la documentazione si riferisce a una funzione in C, sotto Android in Java non esistono i puntatori quindi i dati devono essere scritti in un oggetto Buffer.

adb logcat | tee /tmp/logcat | grep TAG

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #2 il: 04 Febbraio 2013, 23:04:57 CET »
0
Grazie per la risposta,
 in effetti io uso il metodo glReadPixels  in questo modo:

Codice (Java): [Seleziona]
int b[] = new int[Width * Height];
        IntBuffer ib = IntBuffer.wrap(b);
        ib.position(0);
        gl.glReadPixels(0, 0, Width, Height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);

        // The bytes within the ints are in the wrong order for android, but convert into a
        // bitmap anyway. They're also bottom-to-top rather than top-to-bottom. We'll fix
        // this up soon using some fast API calls.
        Bitmap glbitmap = Bitmap.createBitmap(b, Width, Height, Bitmap.Config.ARGB_4444);
        ib = null; // we're done with ib
        b = null; // we're done with b, so allow the memory to be freed

        final float[] cmVals = { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 };

        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(cmVals))); // our R<->B swapping paint

        Bitmap bitmap = Bitmap.createBitmap(Width, Height, Config.ARGB_4444); // the bitmap we're going to draw onto
        Canvas canvas = new Canvas(bitmap); // we draw to the bitmap through a canvas
        canvas.drawBitmap(glbitmap, 0, 0, paint); // draw the opengl bitmap onto the canvas, using the color swapping paint
        glbitmap = null; // we're done with glbitmap, let go of its memory

        // the image is still upside-down, so vertically flip it
        Matrix matrix = new Matrix();
        matrix.preScale(1.0f, -1.0f); // scaling: x = x, y = -y, i.e. vertically flip
        Bitmap bm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); // new bitmap, using the flipping matrix
        saveImage(bm, context);

Solo che mi restituisce un'immagine totalmnte nera.
Penso che il problema sia dove chiamo il metodo e forse il file GL10 non è caricato è possibile che sia questa la motivazione?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #3 il: 04 Febbraio 2013, 23:43:34 CET »
0
La documentazione impone un importante vincolo:

Citazione
...
Values for pixels that lie outside the window connected to the current GL context are undefined.
...

il GL context non ha nulla a che vedere con il context delle API di Android, non puoi chiamare quella funzione dove vuoi, il GL context deve essere attivo.
adb logcat | tee /tmp/logcat | grep TAG

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #4 il: 05 Febbraio 2013, 00:28:59 CET »
0
quindi secondo te in quale metodo dovrei chiamarlo?

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #5 il: 05 Febbraio 2013, 00:52:33 CET »
+1
Via Java con API di Android non hai tante scelte, nei metodi onSurfaceCreated o onSurfaceChanged o onDrawFrame della classe che deriva da GLSurfaceView.Renderer (mi pare abbastanza ovvio).


adb logcat | tee /tmp/logcat | grep TAG

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #6 il: 05 Febbraio 2013, 09:09:04 CET »
0
Non avevo specificato una cosa probabilmente importante, usando l'OpenGL ho utilizzato un GLSurfaceView e non una SurfaceView, per quanto riguarda il tentativo di catturare un'immagine da questo oggetto cambia qualche cosa?
Grazie

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #7 il: 05 Febbraio 2013, 10:06:07 CET »
0
... usando l'OpenGL ho utilizzato un GLSurfaceView e non una SurfaceView

Non ho mai indicato la SurfaceView, ho indicato la GLSurfaceView (la quale deriva da SurfaceView) ?


adb logcat | tee /tmp/logcat | grep TAG

Offline tonnuns

  • Utente junior
  • **
  • Post: 81
  • Respect: +1
    • Mostra profilo
  • Sistema operativo:
    Windows
Re:Catturare in una Bitmap l'output di una SurfaceView
« Risposta #8 il: 05 Febbraio 2013, 20:23:12 CET »
0
Sono stato io a nominare una SurfaceView mentre invece uso una GLSurfaceView.

Comunque ho risolto, come pensavo avevo messo nel punto sbagliato la chiamata al codice sopra indicato.
Grazie