需求:截取相机画面保存为图片,可以拼接多张截图来实现滚动截图效果;
问题:安卓端截图,生成 Texture2D 后发现物体没有被渲染,只有天空盒;
解决方法:修改材质的 Render Mode
相机抓取 Texture2D,此处保存方法暂时注释
IEnumerator IEShot()
{
yield return new WaitForEndOfFrame();
RenderTexture renderTexture = new RenderTexture(Screen.width, Screen.height, 0);
mCameraMain.targetTexture = renderTexture;
mCameraMain.Render();
RenderTexture.active = renderTexture;
Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGBA32, false);
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
texture.Apply();
mCameraMain.targetTexture = null;
RenderTexture.active = null;
Destroy(renderTexture);
mRawImageTest.texture = texture;
mRawImageTest.rectTransform.sizeDelta = new Vector2(texture.width / 4, texture.height / 4);
//SaveTexture(texture);
}
保存 Texture2D
public static void SaveTexture(Texture2D texture)
{
string namepng = GetNameShot();
string path = GetSavePath(namepng);
byte[] bytes = texture.EncodeToJPG();
File.WriteAllBytes(path, bytes);
Debug.Log($"--保存截图 {path}");
}
Texture2D 拼接
public static Texture2D MergeTextureVertical(Texture2D tex1, Texture2D tex2)
{
Debug.Log($"--MergeTextureVertical {Time.realtimeSinceStartup}");
Texture2D res = null;
if (tex1.width != tex2.width)
{
return res;
}
int width = tex1.width;
int height = tex1.height + tex2.height;
res = new Texture2D(width, height, tex1.format, false);
res.SetPixels32(0, 0, width, tex1.height, tex1.GetPixels32());
Color32[] color = tex2.GetPixels32();
int xStart = 0;
int yStart = tex1.height;
res.SetPixels32(xStart, yStart, width, tex2.height, tex2.GetPixels32());
res.Apply();
Debug.Log($"--MergeTextureVertical End {Time.realtimeSinceStartup}");
return res;
}
相机配置
修改材质
————————————————————————————————————————
其他一些方法,方便直接复制
//拼接测试,间隔1S的两张截图垂直拼接成一张
IEnumerator IEScrollShot()
{
Debug.Log($"--IEScrollShot {Time.realtimeSinceStartup}");
yield return new WaitForEndOfFrame();
RenderTexture rt1 = new RenderTexture(Screen.width, Screen.height, 0);
mCameraMain.targetTexture = rt1;
mCameraMain.Render();
RenderTexture.active = rt1;
Texture2D texture1 = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
texture1.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
texture1.Apply();
mCameraMain.targetTexture = null;
RenderTexture.active = null;
Destroy(rt1);
Debug.Log($"--IEScrollShot 第1张图生成完毕 {Time.realtimeSinceStartup}");
yield return new WaitForSecondsRealtime(1f);
yield return new WaitForEndOfFrame();
RenderTexture rt2 = new RenderTexture(Screen.width, Screen.height, 0);
mCameraMain.targetTexture = rt2;
mCameraMain.Render();
RenderTexture.active = rt2;
Texture2D texture2 = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
texture2.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
texture2.Apply();
mCameraMain.targetTexture = null;
RenderTexture.active = null;
Destroy(rt2);
Debug.Log($"--IEScrollShot 第2张图生成完毕 {Time.realtimeSinceStartup}");
Texture2D res = MergeTextureVertical(texture1, texture2);
SaveTexture(res);
Debug.Log($"--IEScrollShot End {Time.realtimeSinceStartup}");
}
// 截图名字生成
static string GetNameShot()
{
DateTime now = DateTime.Now;
StringBuilder sb = new StringBuilder(now.Year.ToString());
sb.Append(now.Month.ToString());
sb.Append(now.Day.ToString());
sb.Append(now.Hour.ToString());
sb.Append(now.Minute.ToString());
sb.Append(now.Second.ToString());
sb.AppendFormat("_{0}.{1}", (int)(Time.realtimeSinceStartup * 1000f), "jpg");
return sb.ToString();
}
// 获取保存路径
static string GetSavePath(string name)
{
StringBuilder sb = new StringBuilder();
#if UNITY_EDITOR
sb.Append(Application.persistentDataPath);
#endif
#if UNITY_ANDROID
sb.Append("/sdcard/DCIM");
#endif
#if UNITY_IOS
sb.Append(Application.persistentDataPath);
#endif
sb.Append("/UMI/ScreenCapture");
Debug.Log($"--Capture Path {sb.ToString()}");
if (!Directory.Exists(sb.ToString()))
{
//创建
Directory.CreateDirectory(sb.ToString());
}
sb.Append("/");
sb.Append(name);
return sb.ToString();
}