2017-07-14 8 views
1

Wir entwickeln eine Anwendung auf Unity3D, die das Bild vom Bildschirm nehmen und auf Texture2D übertragen soll. Wir haben Schwierigkeiten mit der Leistung von (schwachen) Geräten.
Der Code ist unten angegeben. Wir machen einen Screenshot, dann lesen wir Pixel (ReadPixels) - hier entsteht das Problem, eine App läuft furchtbar langsam.RenderTexture zu Texture2D ist sehr langsam

Wir haben versucht, die Textur von der Kamera zu nehmen, aber es funktioniert nicht, weil unser Scanner parallel zu Kudan arbeitet und wiederum den Zugriff auf die Kamera blockiert. Dann haben wir versucht, den zu scannenden Bildschirmbereich einzuschränken (indem wir ein kleines Fenster scannen, aber nicht den ganzen Bildschirm) - aber es gab keine sichtbare Steigerung der Leistung.
Kann mir jemand helfen?
Hier ist unser Code:

IEnumerator DecodeScreen() 
{ 
    yield return new WaitForEndOfFrame(); 
    RenderTexture RT = new RenderTexture(Screen.width, Screen.height,24); 
    Texture2D screen = new Texture2D(RT.width, RT.height, TextureFormat.RGB24, false, false); 
    screen.ReadPixels(new Rect(0, 0, RT.width, RT.height), 0, 0); 
    screen.Apply(); 
    Debug.Log(resultText.text); 
    GetComponent().targetTexture = null; 
    Destroy(RT); 
} 

Antwort

1

Es gibt nur wenige Möglichkeiten, um diesen Code oder optional Art und Weise zu verbessern RenderTexture zu Texture2D zu konvertieren.

.Declare WaitForEndOfFrame als eine Variable außerhalb der Funktion, so dass Sie nicht jedes Mal, dass diese Funktion aufgerufen wird.

. Sie erstellen ein neues Texture2D jedes Mal, wenn Sie diese Funktion aufrufen. Tun Sie das einmal in der Start Funktion dann wieder verwenden. Sie können die Textur frei ändern, wenn sich die Breite oder Höhe ändert.

. Sie erstellen auch neue RenderTexture jedes Mal, wenn Sie diese Funktion auch aufrufen. Es ist schneller, RenderTexture.GetTemporary zu verwenden, um RenderTexture vorübergehend zu erhalten. Wenn Sie damit fertig sind, können Sie es freigeben RenderTexture.ReleaseTemporary.

Texture2D screen = null; 
WaitForEndOfFrame frameEndWait = new WaitForEndOfFrame(); 

void Start() 
{ 
    screen = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false, false); 
} 

IEnumerator DecodeScreen() 
{ 
    yield return frameEndWait; 
    RenderTexture RT = RenderTexture.GetTemporary(Screen.width, Screen.height, 24); 
    //Resize only when Texture2D is null or when its size changes 
    if (screen == null || screen.width != RT.width || screen.height != RT.height) 
    { 
     screen.Resize(RT.width, RT.height, TextureFormat.RGB24, false); 
     //screen = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false, false); 
    } 
    screen.ReadPixels(new Rect(0, 0, RT.width, RT.height), 0, 0); 
    screen.Apply(); 
    RenderTexture.ReleaseTemporary(RT); 
} 

Hier sind andere Optionen haben Sie:

Verwenden native Plugins mit C++:

RenderTexture.GetNativeTexturePtr() zu einer nativen Seite Ihres C senden ++ dann eine OpenGL-Textur aus, dass erstellen und laden Sie es aus C# mit Zeiger mit der Texture2D.CreateExternalTexture Funktion und aktualisieren Sie es mit der Texture2D.UpdateExternalTexture Funktion.


Der schnellste Weg, dies zu tun ist, um RenderTexture verlassen. Verwenden Sie OpenGL glReadPixels Funktion, um Screenshot von C++ Seite zu nehmen, dann senden Sie das Bild mit Zeiger an Unity und laden Sie es mit der Texture2D.CreateExternalTexture Funktion und aktualisieren Sie es mit der Texture2D.UpdateExternalTexture Funktion. Sie können den Mauspixelcode von meinem other post ändern und es machen lassen.