-1

When converting a texture2D to string and then from string back to texture2D I've noticed a drop in quality and for the colours to be lighter.

My current setup (during play-mode) is as follows:

  • Take screenshot of whatever object is in front of the camera
  • Set the sprite of an image as the screenshot (screenshot appear fine here)
  • Convert screenshot (texture2D) to string (this is so that it can be saved)
  • Convert string back to texture2D
  • Set the sprite of an image to the converted texture2D (this is were the image is appearing lighter and is of a lower quality)

Here is the code I am using for the conversion:

// Convert texture2D to string and return
public static string Texture2DToBase64(Texture2D texture)
{
    byte[] data = texture.EncodeToPNG();
    return Convert.ToBase64String(data);
}

// Convert string to texture2D and return
public static Texture2D Base64ToTexture2D(string encoded)
{
    byte[] data = Convert.FromBase64String(encoded);

    int width, height;
    GetImageSize(data, out width, out height);

    Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false, true);
    
    texture.hideFlags = HideFlags.HideAndDontSave;
    texture.filterMode = FilterMode.Point;
    texture.LoadImage(data);

    return texture;
}

static void GetImageSize(byte[] imageData, out int width, out int height)
{
    width = ReadInt(imageData, 3 + 15);
    height = ReadInt(imageData, 3 + 15 + 2 + 2);
}

static int ReadInt(byte[] imageData, int offset)
{
    return (imageData[offset] << 8) | imageData[offset + 1];
}

Here is an example of what a screenshot looks like before conversion:

Screenshot Normal

Here is an example of the same screenshot after conversion:

Screenshot Converted

how I can convert the screenshot (texture2D) to string and then back to texture2D without the quality of the image changing? (or if that is even possible)

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • In your `Texture2D` constructor you set `mipChain = false, linear = true` ..you also set the `texture.filterMode = FilterMode.Point;` is your original texture in the same linear color space and uses the same settings? – derHugo Feb 24 '23 at 17:01
  • are you sure `texture.EncodeToPNG();` isn't degrading it? You should save that to file and check it there too. – Andy Feb 24 '23 at 17:03
  • Also from `EncodeToPNG`: `the encoded PNG data will be in grayscale. PNG data will not contain gamma correction or color profile information.` – derHugo Feb 24 '23 at 17:04
  • If it is about pure Unity to Unity transfer using [`GetPixels`](https://docs.unity3d.com/ScriptReference/Texture2D.GetPixels.html) directly might be easier than going through a `PNG` file data .. you can use `Buffer.BlockCopy` to directly convert between `Color[]` and `byte[]` and back – derHugo Feb 24 '23 at 17:07

1 Answers1

0

Modifying the "linear" parameter in our Texture2D call to false fixed the issue for us:

Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false, false);