Unity3.4 + Androidでスクリーンキャプチャ

Untiy3.4 + Androidの環境では
Application.CaptureScreenshot("screenshot.png");
スクリーンショットを取ると、
保存されたPNGファイルが壊れるという現象が起こります。


これは、既知のバグであり3.5 beta1では修正されているようですが、
急ぎで必要だったためJPGで保存する回避策を試してみました。


JPGへのエンコードにはUnityのフォーラムで提供されているJPGEncoderを使います。
http://forum.unity3d.com/threads/31737-Convert-PNG-to-JPG-without-writing-to-disk


これを使ってスクリーンショットを取るJPGScreenShot.csスクリプトを作成しました。

using UnityEngine;
using System.Collections;
using System.IO;

public class JPGScreenShot : MonoBehaviour
{

	// Use this for initialization
	void Start ()
	{
		Debug.Log ("Taking JPGScreenShot");
		StartCoroutine (ScreenShot ());
	}

	IEnumerator ScreenShot ()
	{
		// エンコーダに渡すテクスチャの作成
		Texture2D tex = new Texture2D (Screen.width, Screen.height, TextureFormat.RGB24, false);
		// バッファをテクスチャに書きこむ
		tex.ReadPixels (new Rect (0, 0, Screen.width, Screen.height), 0, 0);
		tex.Apply ();
		
		// split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
		yield return new WaitForSeconds (0.1f);
		
		// エンコーダ作成
		JPGEncoder encoder = new JPGEncoder (tex, 75.0f);//
		// エンコード開始
		encoder.doEncoding();
		
		// エンコード終了まで待機
		while (!encoder.isDone) {
			yield return new WaitForSeconds (1f);
		}
		
		// ファイル書き出し
		Debug.Log ("Write to : " + Application.persistentDataPath + "/screenshot.jpg");
		File.WriteAllBytes (Application.persistentDataPath + "/screenshot.jpg", encoder.GetBytes ());
		
	}
}


呼び出しは、こんな感じで。

    //Javascriptから
    (new GameObject()).AddComponent("JPGScreenShot");
    //C#スクリプトから
    (new GameObject()).AddComponent(tyepof(JPGScreenShot));


きっとすぐに3.5が出るのであんまり使う機会はないかも。。。
取り敢えずメモ。

追記:
これを使うには、JPGEncoder.csが必要です。
ダウンロードはこちらから
http://bit.ly/jpgencoder