2016-03-27 10 views
5

Ich versuche, jeden Rahmen von einem TextureView zu bekommen, leider versuchen:Lassen Sie sich von TextureView Bitmap effizient

textureView.getBitmap(); 

Ergebnisse in geringer Leistung ist es ein schneller Weg, um eine Bitmap zu erhalten. Ist es besser, stattdessen den NDK zu verwenden?

der Suche nach konkreten Beispielen

+0

Haben Sie es tatsächlich geschafft, Bitmap von TextureView schneller zu erhalten? –

Antwort

3

A TextureView empfängt Frames auf einem SurfaceTexture, die Rahmen gesendet nimmt seine Oberfläche und wandelt sie in eine GLES-Textur um. Um die Pixeldaten zu erhalten, muss die Textur in einen Framebuffer gerendert und dann mit glReadPixels() ausgelesen werden. Die Pixeldaten können dann mit einem Bitmap-Objekt umhüllt werden (was das Kopieren der Pixeldaten beinhalten kann oder nicht).

Die Verwendung des NDK wird Ihnen nicht viel nützen, da der gesamte Code, der schnell ausgeführt werden muss, bereits nativ implementiert ist.

Möglicherweise sehen Sie eine Verbesserung, indem Sie die Daten direkt an ein SurfaceTexture senden und die GLES-Arbeit selbst erledigen. Aber vermutlich möchten Sie die eingehenden Frames in der TextureView anzeigen, sodass Sie nur den Bitmap-Overhead speichern können kann oder kann nicht signifikant sein).

Es könnte hilfreich sein, wenn Sie in Ihrer Frage erklärt haben, woher die Frames kommen und was Sie damit machen wollen.

+0

Ich möchte die Think-Bilderkennung des Frames bearbeiten. So Echtzeit-Erkennung auf den Frames das Problem gerade jetzt ist, dass Aufruf von .getBitmap() etwa ~ 50-60 ms dauert. Ich kann das lösen, indem ich die Bitmap verkleinere, was die Zeit reduziert, aber dann möchte ich die Frames wieder in der Texturansicht anzeigen lassen. Wie würden Sie vorschlagen, dass ich selbst die GLES-Arbeit mache? – AndyRoid

+0

GLES Rendering + 'glReadPixels()' sollte viel schneller sein. Wenn Ihre Anzeigeanforderungen einfach sind (über der Ansichtsebene oder ganz darunter), können Sie die Textur einfach in eine SurfaceView rendern. Sie würden also Ihre eingehenden Frames auf ein SurfaceTexture richten und die Textur in eine SurfaceView rendern, indem Sie 'glReadPixels()' vor 'eglSwapBuffers()' aufrufen, um eine Kopie der Pixel zu erhalten. Dadurch erhalten Sie einen direkten Byte-Puffer mit RGB-Pixeln, die Sie aus Java-Code oder C++ verwenden können. Ich habe kein genaues Beispiel dafür, aber die verschiedenen Stücke finden Sie in Grafika (https://github.com/google/grafika). – fadden

+0

Vielen Dank für die ausführliche Antwort! – AndyRoid

-4

Eine Möglichkeit zur Optimierung ist im Hintergrund in einer asynchronen Aufgabe wie folgt auszuführen:

private class AsyncTaskRunner extends AsyncTask<> 
{ 

     @Override 
     protected void doInBackground() 
     { 

     // this is where you put long operations in background 
      textureView.getBitmap(); 

     } 
} 
+0

Haben Sie das tatsächlich getestet? – AndyRoid

+1

Ihre Antwort ist völlig falsch, da Sie .getBitmap nicht vom UI-Thread aus aufrufen können. – AndyRoid

+2

Außerdem wird AsyncTask mit einer niedrigeren Priorität ausgeführt, daher ist es keine gute Idee, es zu verwenden, wenn die Leistung wichtig ist. – fadden

Verwandte Themen