2016-03-27 31 views
5

Próbuję dostać każdą klatkę z TextureView niestety stara:Get bitmapy z TextureView skutecznie

textureView.getBitmap(); 

Wyniki w niskiej wydajności jest jakiś szybszy sposób, aby uzyskać bitmapy. Czy zamiast tego lepiej używać NDK?

Patrząc na rzeczywistych przykładach

+0

Czy udało Ci się przyspieszyć otrzymywanie bitmapy z TextureView? –

Odpowiedz

3

TextureView odbiera ramki na SurfaceTexture, który odbywa ramek wysyłanych do jego Surface i przekształca je w teksturę GLES. Aby uzyskać dane piksela, teksturę należy renderować do bufora ramki, a następnie odczytać przy pomocy glReadPixels(). Dane pikselowe można następnie opakować za pomocą obiektu Bitmap (który może, ale nie musi obejmować kopiowania danych pikseli).

Korzystanie z NDK nie przyniesie Ci wiele dobrego, ponieważ cały kod, który musi działać szybko, jest już wdrożony natywnie.

Możliwe, że zauważysz pewną poprawę, wysyłając dane bezpośrednio do SurfaceTexture i wykonując pracę GLES samodzielnie, ale prawdopodobnie chcesz wyświetlić przychodzące klatki w TextureView, więc wszystko, co możesz potencjalnie zapisać, to obciążenie bitmapowe (które może być lub może nie być znaczący).

To może pomóc, jeśli wyjaśnisz w swoim pytaniu, skąd pochodzą ramki i co chcesz z nimi zrobić.

+0

Chcę wykonać pewne przetwarzanie na rozpoznawanie obrazu myślowego ramki. Tak więc rozpoznawanie w czasie rzeczywistym ramek stanowi obecnie problem polegający na tym, że wywołanie metody .getBitmap() trwa około ~ 50-60 ms. Mogę to rozwiązać, zmniejszając bitmapę, co redukuje czas, ale potem chcę ponownie wyświetlić ramki z powrotem do widoku tekstury. Jak zaproponowałbyś, że sam wykonam pracę GLES? – AndyRoid

+0

Wyświetlanie GLES + 'glReadPixels()' powinno być znacznie szybsze. Jeśli twoje wymagania wyświetlania są proste (na górze warstwy widoku lub całkowicie pod nią), możesz po prostu wyrenderować teksturę do SurfaceView. Więc możesz skierować przychodzące klatki do SurfaceTexture i renderować teksturę do SurfaceView, wywołując 'glReadPixels()' przed 'eglSwapBuffers()', aby pobrać kopię pikseli. To da ci bezpośredni bufor bajtowy z pikselami RGB, który możesz wykorzystać z kodu Java lub C++. Nie mam dokładnego przykładu do zaoferowania, ale różne elementy można znaleźć w Grafika (https://github.com/google/grafika). – fadden

+0

Dziękuję za szczegółową odpowiedź! – AndyRoid

-4

Jednym ze sposobów optymalizacji jest uruchamiane w tle w asynchronicznym zadania jak ten:

private class AsyncTaskRunner extends AsyncTask<> 
{ 

     @Override 
     protected void doInBackground() 
     { 

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

     } 
} 
+0

Czy faktycznie to testowałeś? – AndyRoid

+1

Twoja odpowiedź jest całkowicie błędna, ponieważ nie można wywołać .getBitmap off wątku interfejsu użytkownika. – AndyRoid

+2

Ponadto AsyncTask działa z niższym priorytetem, więc nie jest dobrym pomysłem użycie go, gdy wydajność jest ważna. – fadden