8th Wall XR for Unity:将现实纹理保存到磁盘
8th Wall XR for Unity: Saving RealityTexture to disk
我正在尝试使用此代码将相机的提要保存为 png,但它似乎无法正常工作:
void RecordAndSaveFrameTexture()
{
if (mXr.ShouldUseRealityRGBATexture())
{
SaveTextureAsPNG(mXr.GetRealityRGBATexture(), mTakeDirInfo.FullName + "/texture_" + mFrameInfo.mFrameCount.ToString() + ".png");
}
else
{
SaveTextureAsPNG(mXr.GetRealityYTexture(), mTakeDirInfo.FullName + "/texture_y_" + mFrameInfo.mFrameCount.ToString() + ".png");
SaveTextureAsPNG(mXr.GetRealityUVTexture(), mTakeDirInfo.FullName + "/texture_uv_" + mFrameInfo.mFrameCount.ToString() + ".png");
}
}
public static void SaveTextureAsPNG(Texture2D aTexture, string aFullPath)
{
byte[] bytes = aTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(aFullPath, bytes);
Debug.Log("Image with Instance ID:" + aTexture.GetInstanceID() + "with dims of " + aTexture.width.ToString() + " px X " + aTexture.height + " px " + " with size of" + bytes.Length / 1024 + "Kb was saved as: " + aFullPath);
}
在非 ArCore 上测试 android 我得到正确尺寸为 480 x 640 像素的黑色图像(具有随机彩色像素)。使用 ArCore,它是一个 0kb 的黑色图像。
直接从这些纹理创建图像无法正常工作,因为此数据在渲染有效图像之前要通过 XRCameraYUVShader
和 XRARCoreCamera
。
一个选项是创建 XRVideoController
的自定义版本,它提供对用于渲染相机源的 material 的访问。从那里,您的代码可以这样修改:
void RecordAndSaveFrameTexture() {
Texture2D src = xr.ShouldUseRealityRGBATexture()
? xr.GetRealityRGBATexture()
: xr.GetRealityYTexture();
RenderTexture renderTexture = new RenderTexture (src.width, src.height, 0, RenderTextureFormat.ARGB32);
Graphics.Blit (null, renderTexture, xrMat);
SaveTextureAsPNG(renderTexture, Application.persistentDataPath + "/texture.png");
}
public static void SaveTextureAsPNG(RenderTexture renderTexture, string aFullPath) {
Texture2D aTexture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBA32, false);
RenderTexture.active = renderTexture;
aTexture.ReadPixels(new Rect(0, 0, aTexture.width, aTexture.height), 0, 0);
RenderTexture.active = null;
byte[] bytes = aTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(aFullPath, bytes);
}
其中 xrMat
是用于呈现相机画面的 material。
这将提供 没有 任何 Unity 游戏对象的相机图像。如果您希望游戏对象显示在保存的图像中,您可以覆盖 OnRenderImage
来实现:
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (shouldSaveImageFrame) {
SaveTextureAsPNG(src, Application.persistentDataPath + "/_rgbatexture.png");
shouldSaveImageFrame = false;
}
Graphics.Blit (src, dest);
}
其中 shouldSaveImageFrame
是您在别处设置的标志,以防止在每一帧上保存图像。
我正在尝试使用此代码将相机的提要保存为 png,但它似乎无法正常工作:
void RecordAndSaveFrameTexture()
{
if (mXr.ShouldUseRealityRGBATexture())
{
SaveTextureAsPNG(mXr.GetRealityRGBATexture(), mTakeDirInfo.FullName + "/texture_" + mFrameInfo.mFrameCount.ToString() + ".png");
}
else
{
SaveTextureAsPNG(mXr.GetRealityYTexture(), mTakeDirInfo.FullName + "/texture_y_" + mFrameInfo.mFrameCount.ToString() + ".png");
SaveTextureAsPNG(mXr.GetRealityUVTexture(), mTakeDirInfo.FullName + "/texture_uv_" + mFrameInfo.mFrameCount.ToString() + ".png");
}
}
public static void SaveTextureAsPNG(Texture2D aTexture, string aFullPath)
{
byte[] bytes = aTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(aFullPath, bytes);
Debug.Log("Image with Instance ID:" + aTexture.GetInstanceID() + "with dims of " + aTexture.width.ToString() + " px X " + aTexture.height + " px " + " with size of" + bytes.Length / 1024 + "Kb was saved as: " + aFullPath);
}
在非 ArCore 上测试 android 我得到正确尺寸为 480 x 640 像素的黑色图像(具有随机彩色像素)。使用 ArCore,它是一个 0kb 的黑色图像。
直接从这些纹理创建图像无法正常工作,因为此数据在渲染有效图像之前要通过 XRCameraYUVShader
和 XRARCoreCamera
。
一个选项是创建 XRVideoController
的自定义版本,它提供对用于渲染相机源的 material 的访问。从那里,您的代码可以这样修改:
void RecordAndSaveFrameTexture() {
Texture2D src = xr.ShouldUseRealityRGBATexture()
? xr.GetRealityRGBATexture()
: xr.GetRealityYTexture();
RenderTexture renderTexture = new RenderTexture (src.width, src.height, 0, RenderTextureFormat.ARGB32);
Graphics.Blit (null, renderTexture, xrMat);
SaveTextureAsPNG(renderTexture, Application.persistentDataPath + "/texture.png");
}
public static void SaveTextureAsPNG(RenderTexture renderTexture, string aFullPath) {
Texture2D aTexture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGBA32, false);
RenderTexture.active = renderTexture;
aTexture.ReadPixels(new Rect(0, 0, aTexture.width, aTexture.height), 0, 0);
RenderTexture.active = null;
byte[] bytes = aTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(aFullPath, bytes);
}
其中 xrMat
是用于呈现相机画面的 material。
这将提供 没有 任何 Unity 游戏对象的相机图像。如果您希望游戏对象显示在保存的图像中,您可以覆盖 OnRenderImage
来实现:
void OnRenderImage(RenderTexture src, RenderTexture dest) {
if (shouldSaveImageFrame) {
SaveTextureAsPNG(src, Application.persistentDataPath + "/_rgbatexture.png");
shouldSaveImageFrame = false;
}
Graphics.Blit (src, dest);
}
其中 shouldSaveImageFrame
是您在别处设置的标志,以防止在每一帧上保存图像。