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

Posted

技术标签:

【中文标题】我想将图像数据(Texture2D)转换为 Base64 字符串并存储在 Unity3D(C#)中的 JSON 文件中【英文标题】:I want to convert image data(Texture2D) to Base64 string and store in JSON file in Unity3D(C#) 【发布时间】:2021-09-29 21:32:11 【问题描述】:

我想将图像(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#

【问题讨论】:

为什么需要解析为 json ?您是否有其他带有 PNG 的数据,您需要包含它吗? 您不应该将整个 png 存储为 json,并不是说这是不可能的,而是有点错误。最好将其存储为字节数组,然后将路径存储在json中。 如果这是一个网络请求,为什么不使用MultipartFormFileSection 通过UnityWebRequest.Post 发送二进制数据?你能告诉我们你到底想达到什么目标吗? @derHugo 我的目标是我创建了多个图像捕获,我可以从实时渲染相机捕获图像并将其保存到我的本地资产文件夹它运行良好并且正在获取 Texture2D 但现在我需要转换图像数据到 Base64 字符串并存储在 JSON 文件中。每次我捕获/删除图像时,它应该更新 JSON 文件,下次启动应用程序时,它应该首先读取 JSON 文件,如果找到任何图像数据,应该在我创建的滚动视图中显示它. @AliHussain 为什么仍然是 JSON?为什么不简单地将最后一个文件存储为实际的 PNG 图像文件? 【参考方案1】:

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

例如这条线在做什么?

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);

【讨论】:

【参考方案2】:

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

但是,我仍然会回答这个问题,但请避免这种情况。 如果您想将此字符串另存为 json,则必须指定其可序列化为 c# 将字符串视为不适合序列化(这是错误的:Is String not serializable by default in .Net Core?),将其添加到您的字符串后面,您的代码应该可以工作(如果您想知道这称为属性,它有点像标签):

[Serializable]

现在,为了正确执行此操作,我们将从统一文档中获取示例代码(顺便说一下,这是一个非常有用的工具): 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");

【讨论】:

感谢您的回复,您分享的代码正在创建 JSON 文件,但不是 JSON 格式,JSON 文件具有此类字符:'âPNG IHDR8ħp] IDATxÏΩÀñ‰ºÚ› W◊æ|ÁHiŸœÊ''O,ôGxy,ß≥§%À÷˘∫ªÓ˛ÌâA2 fiA&≤´3q DÏÿdíÙ˚ˇÈ˘FLÓŒˇˇÌ,¯â&VSúhÇÿ° ' 请建议我可以将此数据发送到服务器.所以我不能直接在 web 请求中发送纹理,我需要将其转换为 basestring,并且需要将整个数据转换为 JSON。 [Serializable] 属性适用于 types 而不是字符串变量/字段(?不太明白你说 OP 应该在哪里添加这个) 而且你知道 OP 已经在原始代码中使用texture.EnciodeToPNG ^^ 要通过 webrequest 发送纹理使用二进制数据而不是字符串,您必须使用 AddBinaryData。 @Lila 大多数问题都是将数据转换为二进制然后转换为 JSON,您能否在示例中演示如何实现这一点,实际上我在 C#、Unity 中的经验不足。跨度>

以上是关于我想将图像数据(Texture2D)转换为 Base64 字符串并存储在 Unity3D(C#)中的 JSON 文件中的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET 中将 base64 图像 URL 转换为用户友好 URL

如何使用 C# 脚本在 Unity 中将 OpenCV Mat 转换为 Texture2D?

将图像加载为 Texture2D

UE4 从 C++ 创建纹理

如何将 HTML 表格转换为图像?

上传图像/文件并将其转换为 mysql 数据库