2016-03-23 2 views
2

私はそれぞれの変形を試みました:http://wiki.unity3d.com/index.php/ScreenCapture Afterall、単純なApplication.Capturescreenshot(...)は、最も遅いです。遅れのないUnity3Dのスクリーンショットを撮る

、教えてください、私は遅れずにスクリーンショットを取ることができますどのように? Androidのゲームにはたくさんの機能があるため、不可能ではありません。

+0

あなたが代わりに実行されたコルーチンでそれを保存する別のスレッドでスクリーンショットを救うことができます – RCYR

+0

@RCYR Capturescreenshotはメインスレッドからのみ呼び出すことができます – Programmer

+0

スクリーンショットビデオの作成中にフレームレートを変更するためのコマンドは何ですか?ここにはここで質問がありました.. – Fattie

答えて

1

Application.CaptureScreenshot()は一般的に遅い、より高速な方法は、あなたがハードドライブにテクスチャをエンコードして保存することができますよりもTexture2Dを使用してReadPixels()機能を使用して、その上に画面上のすべてのピクセルを読むことです。

これは、この方法の例です:

Texture2D screenShot = new Texture2D(Screen.width, Screen.height); 
screenShot.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0); 
screenShot.Apply(); 
byte[] bytes = tex.EncodeToPNG(); 
Object.Destroy(tex); 
File.WriteAllBytes(Application.dataPath + "/../myScreenShot.png", bytes); 

あなたはユニティスクリプティングリファレンスページhereを使用することができます完全な参考のために。あなたは、各ステップの後を待っずに同時にですべてのステップを実行しようとすると、

+0

'ReadPixels()'は、現在のコマンドバッファ内の残りのすべてのコマンドを待つことを意味するGPUフラッシュをトリガするため、非常に遅いです – Aray

6

原因の遅れ写真を撮影中です。これを修正するには、を1回実行し、が多く、フレームを待ってから、次の操作を実行してからをもう一度待ちます。あなたがゲームプレイ中に保存することを決定した場合や、画像を保存してスレッドを使用しています。 EncodeToPNG()は問題別ですが、私はそれでは約ソリューション後でお話します。あなたが、その後すぐにゲームが起動している間、それを表示するスクリーンショットを取りたい場合は、以下の

コードが良いです。 これは正しい方法で撮影し、約1.5秒でファイルを保存します。

IEnumerator screenShotCoroutine() 
{ 
    yield return new WaitForEndOfFrame(); 
    string path = Application.persistentDataPath + "/DrukaloScreenshot.png"; 

    Texture2D screenImage = new Texture2D(Screen.width, Screen.height); 

    //Get Image from screen 
    screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); 

    //Wait for a long time 
    for (int i = 0; i < 15; i++) 
    { 
     yield return null; 
    } 

    screenImage.Apply(); 

    //Wait for a long time 
    for (int i = 0; i < 15; i++) 
    { 
     yield return null; 
    } 

    //Convert to png(Expensive) 
    byte[] imageBytes = screenImage.EncodeToPNG(); 

    //Wait for a long time 
    for (int i = 0; i < 15; i++) 
    { 
     yield return null; 
    } 

    //Create new thread then save image to file 
    new System.Threading.Thread(() => 
    { 
     System.Threading.Thread.Sleep(100); 
     File.WriteAllBytes(path, imageBytes); 
    }).Start(); 
} 

あなたは写真を撮りたいとあなたはすぐに画像を表示するために必要なないある場合は、あなたが/ロードにアクセスしたいときに/表示、Texture2Dとして画像を保存することができます後でからに変換してからPNGに変換してください。これは、EncodeToPNG()が非常にであるため、すぐに画像が必要ない場合は、pngに変換する必要はありません。あなたが実際にPNGとしてにそれを必要とするのみ時にそれを行うことができます。だから今、私たちはただ、その後の後にそれをロードし、「を.pngを」するロードされたイメージを変換する「.t2D」として保存することができます。

にTexture2Dとして保存 ".t2D"

IEnumerator screenShotCoroutine() 
    { 
     yield return new WaitForEndOfFrame(); 
     string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D"; 

     Texture2D screenImage = new Texture2D(Screen.width, Screen.height); 

     //Get Picture 
     screenImage.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0); 

     //Wait for a long time 
     for (int i = 0; i < 15; i++) 
     { 
      yield return null; 
     } 

     screenImage.Apply(); 

     //Wait for a long time 
     for (int i = 0; i < 15; i++) 
     { 
      yield return null; 
     } 

     byte[] rawData = screenImage.GetRawTextureData(); 

     //Wait for a long time 
     for (int i = 0; i < 15; i++) 
     { 
      yield return null; 
     } 

     //Create new thread then save image 
     new System.Threading.Thread(() => 
     { 
      System.Threading.Thread.Sleep(100); 
      File.WriteAllBytes(path, rawData); 
     }).Start(); 
    } 

次に、あなたが実際に画像、負荷にTexture2D "を必要とするとき。T2D「と、その後にそれをひそか」.t2D」「古いものを削除して、その後」を.pngを。

IEnumerator screenShotCoroutine() 
{ 
    string path = Application.persistentDataPath + "/DrukaloScreenshot.t2D"; 
    string newPath = Application.persistentDataPath + "/DrukaloScreenshot.png"; 

    Texture2D screenImage = new Texture2D(Screen.width, Screen.height); 

    byte[] rawData = null; 

    //Create new thread then Load image 
    new System.Threading.Thread(() => 
    { 
     System.Threading.Thread.Sleep(100); 
     rawData = File.ReadAllBytes(path); 
    }).Start(); 

    //Wait for a long time 
    for (int i = 0; i < 9; i++) 
    { 
     yield return null; 
    } 

    //Put loaded bytes to Texture2D 
    screenImage.LoadRawTextureData(rawData); 

    //Wait for a long time 
    for (int i = 0; i < 9; i++) 
    { 
     yield return null; 
    } 

    screenImage.Apply(); 

    //Wait for a long time 
    for (int i = 0; i < 9; i++) 
    { 
     yield return null; 
    } 

    //convert to png 
    byte[] pngByte = screenImage.EncodeToPNG(); 

    //Wait for a long time 
    for (int i = 0; i < 9; i++) 
    { 
     yield return null; 
    } 

    //Do whatever you want with the png file(display to screen or save as png) 


    //Create new thread and Save the new png file, then Delete Old image(DrukaloScreenshot.t2D) 
    new System.Threading.Thread(() => 
    { 
     System.Threading.Thread.Sleep(100); 
     File.WriteAllBytes(newPath, pngByte); //Save the new png file(DrukaloScreenshot.png) 
     File.Delete(path); //Delete old file (DrukaloScreenshot.t2D) 
    }).Start(); 
} 
+0

あなたのコードを使用しましたが、ゲームプレイ中にスクリーンイメージを作成すると同じラグが表示されます。遅れはApplication.Capturescreenshot(...)のように少し気づかないです。とにかく、ありがとう。 – Drukalo

+0

20%betterr – Drukalo

+0

私のソリューションはApplication.Capturescreenshot(...)またはApplication.Capturescreenshot(...)よりも20%優れています。 – Programmer

関連する問題