我想将图像数据(Texture2D)转换为Base64字符串并存储在Unity3D(c#)的JSON文件中



我想将图像(Texture2D)数据转换为Base64字符串并以JSON格式存储。到目前为止,我正在获取图像纹理,这是一种来自实时渲染相机的截图。我希望同样的图像数据变成JSON格式。请给我举个例子。

这就是我如何将纹理转换为Base64然后JSON。

Application.ExternalCall("screenshot", System.Convert.ToBase64String(texture.EncodeToPNG()));
string TextureArray = System.Convert.ToBase64String(texture.EncodeToPNG());
string serializedAbilites = JsonUtility.ToJson(TextureArray);
File.WriteAllText(Application.dataPath + "/File.json", TextureArray);
  • Unity版本:2020.3.11f1,
  • 语言:c#

你的大部分代码我都看不懂

例如:这行做什么?

Application.ExternalCall("screenshot", System.Convert.ToBase64String(texture.EncodeToPNG()));

这应该是某种回调吗?似乎你编码一些纹理的字符串,然后从不使用该字符串的任何东西。

然后再使用texture.EncodeToPNG,这非常昂贵。

那么你已经得到了一个string。所以你眼中的结果应该是

string serializedAbilites = JsonUtility.ToJson(TextureArray);

最后你得到了serializedAbilities但是不管怎样,不要使用它而是写入文件

File.WriteAllText(Application.dataPath + "/File.json", TextureArray);

我猜你宁愿做什么来得到一个JSON将简单地包装成一个有效的JSON对象,如:

{
"content" : "..........Your encoded string here ........."
}

所以你可以很容易地通过使用

实现你想要做的事情
var json = "{"content":"" + TextureArray + ""}";
File.WriteAllText(Path.Combine(Application.dataPath, "File.json"), json);

或者为JSON布局提供一个实际的包装类,如

[Serializable]
public class ImageJson
{
public string content;
}

,然后使用

var imageJson = new ImageJson
{
content = TextureArray 
};
var json = JsonUtility.ToJson(imageJson);
File.WriteAllText(Path.Combine(Application.dataPath, "File.json"), json);

我知道这种回答有点烦人,但这样做是一个坏主意,如果你真的需要保存纹理数据,你应该把它保存为二进制而不是字符串,你会使用更多的字节,使你的代码复杂化,一般来说,这不是一个好的做法。

然而,我仍然会回答这个问题,但请避免这样做。如果你想将这个字符串保存为json,你必须指定它的可序列化性,因为c#认为字符串不适合序列化(这是假的,然而:字符串在。net Core中默认是不可序列化的吗?),在你的字符串后面添加这个,你的代码应该工作(如果你想知道这被称为属性,它有点像标签):

[Serializable]
现在,为了正确地做到这一点,我们将从unity文档中获取示例代码(顺便说一下,这是一个非常有用的工具):Texture2D。EncodeToPNG
// Encode texture into PNG
byte[] bytes = tex.EncodeToPNG();
Object.Destroy(tex);
// For testing purposes, also write to a file in the project folder
// File.WriteAllBytes(Application.dataPath + "/../SavedScreen.png", bytes);

这段代码需要一个纹理2d类,将其转换为字节(就像你已经在做的那样),然后使用File.WriteAllBytes()将其写入二进制。你还应该销毁纹理对象(Object.Destroy(Your texture)),以防止游戏存储不必要的字节,这可能会导致垃圾收集器的延迟峰值(我认为)。

但所有这些对你来说都是无用的,如果你想截图主摄像头,你可以使用unity的内置功能,这也确保了跨平台兼容性:

ScreenCapture.CaptureScreenshot("your path");

如果您需要更高分辨率或更低分辨率的截图,请在路径后添加一个乘数参数,如下所示:

ScreenCapture.CaptureScreenshot("your path", SizeMultiplier);

那么,作为总结,做一些像这样的事情,你应该很好去:

ScreenCapture.CaptureScreenshot(Application.dataPath + "/File.png");