SHAI
SHAI

Reputation: 859

How to EncodeToPng compressed Textures in Unity

I develop an app that saves textures (screenshots) and I need to compress them, but then- I can't use EncodeToPNG method in order to show the image on the screen.

My steps:

  1. Texture2D tex = new Texture2D(recwidth, recheight, TextureFormat.RGB24, false); //RGB24- Because of the next step:

  2. tex.ReadPixels(rex, rdPXX, rdPXY); tex.Apply();

  3. tex.Compress(false);

Later I need to show it on the screen with-

  1. var bytes = tex.EncodeToPNG();

But I can't because as we all know EncodeToPNG doesn't support compressed textures, so what can I do? It takes a lot of space on my mobile

Upvotes: 4

Views: 13979

Answers (1)

Programmer
Programmer

Reputation: 125275

You have to decompress the Texture first before using EncodeToPNG on it. You should be able to do this with RenderTexture. Copy the compressed Texture2D to RenderTexture. Assign the RenderTexture to RenderTexture.active then use ReadPixels to copy the pixels from the RenderTexture to the new Texture2D you wish to be in decompressed format. Now, you can use EncodeToPNG on it.

The helper function to do this:

public static class ExtensionMethod
{
    public static Texture2D DeCompress(this Texture2D source)
    {
        RenderTexture renderTex = RenderTexture.GetTemporary(
                    source.width,
                    source.height,
                    0,
                    RenderTextureFormat.Default,
                    RenderTextureReadWrite.Linear);

        Graphics.Blit(source, renderTex);
        RenderTexture previous = RenderTexture.active;
        RenderTexture.active = renderTex;
        Texture2D readableText = new Texture2D(source.width, source.height);
        readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
        readableText.Apply();
        RenderTexture.active = previous;
        RenderTexture.ReleaseTemporary(renderTex);
        return readableText;
    }
}

Usage:

Create a compressed Texture:

Texture2D tex = new Texture2D(recwidth, recheight, TextureFormat.RGB24, false);
tex.ReadPixels(rex, rdPXX, rdPXY);
tex.Apply();
tex.Compress(false);

Create a new decompressed Texture from the compressed Texture:

Texture2D decopmpresseTex = tex.DeCompress();

Encoded to png

var bytes = decopmpresseTex.EncodeToPNG();

Upvotes: 17

Related Questions