[Unity (C #)] Save related data together with image data
Introduction
[Unity (C #)] Convert texture to image data, save and load in terminal
↑ It is a continuation of the last time.
This time, I would like to add character string information to the saved image data and save it.
Way of thinking
Define a structure with an image and a string as one chunk.
Save the structure as Json format.
Deserialize the structure when loading.
code
The code structure is as follows.
① Structure
② Json conversion Utility class
③ Class to save and load the structure
Structure
First, define the structure.
Since the binary data of the image is written with File.WriteAllBytes
The data to be given to the structure is the path where the image data is saved.
using System;
/// <summary>
///Image data structure
/// </summary>
[Serializable]
public struct ImageData
{
/// <summary>
///Image save destination path
/// </summary>
public string ImageSavePath;
/// <summary>
///Image name
/// </summary>
public string ImageName;
/// <summary>
///constructor
/// </summary>
/// <param name="imageSavePath">Destination path</param>
/// <param name="imageName">Saved name</param>
public ImageData(string imageSavePath,string imageName)
{
this.ImageSavePath = imageSavePath;
this.ImageName = imageName;
}
}
Json conversion Utility class
Next, define a class that converts the structure to Json format.
[Reference link]: [Unity (C #)] Implementation of save and load using JsonUtility
using System;
using System.IO;
using UnityEngine;
/// <summary>
///Implementation of Save and Load functions
/// </summary>
public static class JsonDataUtility
{
/// <summary>
///Write function
/// </summary>
/// <param name="imageData">Data to serialize</param>
public static void Save(ImageData imageData,string path)
{
//Serialize execution
string jsonSerializedData = JsonUtility.ToJson(imageData);
Debug.Log(jsonSerializedData);
//Actually create a file and write
using (var sw = new StreamWriter (path, false))
{
try
{
//Write to file
sw.Write (jsonSerializedData);
}
catch (Exception e) //What to do when it fails
{
Debug.Log (e);
}
}
}
/// <summary>
///Read function
/// </summary>
/// <returns>Deserialized structure</returns>
public static ImageData Load(string path)
{
ImageData jsonDeserializedData = new ImageData();
try
{
//Read the file
using (FileStream fs = new FileStream (path, FileMode.Open))
using (StreamReader sr = new StreamReader (fs))
{
string result = sr.ReadToEnd ();
Debug.Log(result);
//Put the read Json in the structure
jsonDeserializedData = JsonUtility.FromJson<ImageData>(result);
}
}
catch (Exception e) //What to do when it fails
{
Debug.Log (e);
}
//Returns a deserialized struct
return jsonDeserializedData;
}
}
Class to save and load structs
A class that saves and loads structures.
I’m doing a lot of other things, but it’s a sample, so I’m happy with it.
using System.IO;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
///Save and load structs
/// </summary>
public class UseStructData : MonoBehaviour
{
[SerializeField] private Button _saveButton;
[SerializeField] private Button _loadButton;
[SerializeField] private Button _resetButton;
[SerializeField] private InputField _inputField;
[SerializeField] private Text _inputText;
[SerializeField] private Text _loadText;
[SerializeField] private Image _paintImage;
[SerializeField] private Image _loadImage;
[SerializeField] private Painter _painter;
private const string IMAGE_SAVE_FOLDER = "Image";
private const string IMAGE_DATA_SAVE_FOLDER = "ImageData";
private const string PNG = ".png ";
private const string JSON = ".json";
/// /// <summary>
///Get the save destination path
/// </summary>
/// <param name="folderName">Delimited folder name</param>
/// <returns>Destination path</returns>
private string GetSavePath(string folderName,string fileName,string type)
{
string directoryPath = Application.persistentDataPath + "/" + folderName + "/";
if (!Directory.Exists(directoryPath))
{
//Create if it doesn't exist yet
Directory.CreateDirectory(directoryPath);
return directoryPath + fileName + type;
}
return directoryPath + fileName + type;
}
private void Start()
{
//Save button
_saveButton.OnPointerClickAsObservable().Subscribe(_ =>
{
SaveImageData("SoftCream");
//reset
_painter.ResetTexture();
_inputField.text = "";
})
.AddTo(this);
//Load button
_loadButton.OnPointerClickAsObservable().Subscribe(_ => LoadImageData("SoftCream")).AddTo(this);
//Reset button
_resetButton.OnPointerClickAsObservable().Subscribe(_ => _painter.ResetTexture()).AddTo(this);;
}
/// <summary>
///Serialize the structure
/// </summary>
private void SaveImageData(string fileName)
{
string pngPath = GetSavePath(IMAGE_SAVE_FOLDER, fileName, PNG);
string jsonPath = GetSavePath(IMAGE_DATA_SAVE_FOLDER, fileName, JSON);
//Enter the path and name in the structure.
ImageData imageData =new ImageData(pngPath,_inputText.text);
//Convert to png
byte[] bytes = _paintImage.sprite.texture.EncodeToPNG();
//Save
File.WriteAllBytes(pngPath, bytes);
//Convert struct to Json
JsonDataUtility.Save(imageData,jsonPath);
}
/// <summary>
///Convert & load to texture
/// </summary>
private void LoadImageData(string fileName)
{
string jsonPath = GetSavePath(IMAGE_DATA_SAVE_FOLDER, fileName, JSON);
ImageData imageData = JsonDataUtility.Load(jsonPath);
//Read
byte[] bytes = File.ReadAllBytes(imageData.ImageSavePath);
//Convert image to texture
Texture2D loadTexture = new Texture2D(2, 2);
loadTexture.LoadImage(bytes);
//Convert textures to sprites
_loadImage.sprite = Sprite.Create(loadTexture, new Rect(0, 0, loadTexture.width, loadTexture.height), Vector2.zero);
//Show the name of the image
_loadText.text = imageData.ImageName;
}
}
Directory.Exists
The method of creating a new directory and using it as the save destination path has become sober.
Check if the directory exists with Directory.Exists
I got an error if I didn’t prepare the branch process.
if (!Directory.Exists(directoryPath))
{
//Create if it doesn't exist yet
Directory.CreateDirectory(directoryPath);
return directoryPath + fileName + type;
}
demo
Save the elegant illustration and the character string you entered as the name of the illustration,
I succeeded in reading.