Symptoms:
- I want to get pixels from a Texture.
- I do not want to set the Texture as "readable".
Causes:
To use Texture2D.GetPixels, you need to select Read/Write Enabled on Texture Import Settings to enable access to the Texture data from scripts. Sometimes you need to get pixels from a Texture without setting the Texture as readable, similar to how the Unity Editor does it to get preview images from Textures.
Resolution:
You can use a RenderTexture to do that. Take a look at the following code:
"texture" is the texture you want to read which is not marked as readable in the import settings:
// Create a temporary RenderTexture of the same size as the texture RenderTexture tmp = RenderTexture.GetTemporary( texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); // Blit the pixels on texture to the RenderTexture Graphics.Blit(texture, tmp); // Backup the currently set RenderTexture RenderTexture previous = RenderTexture.active; // Set the current RenderTexture to the temporary one we created RenderTexture.active = tmp; // Create a new readable Texture2D to copy the pixels to it Texture2D myTexture2D = new Texture2D(texture.width, texture.height); // Copy the pixels from the RenderTexture to the new Texture myTexture2D.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0); myTexture2D.Apply(); // Reset the active RenderTexture RenderTexture.active = previous; // Release the temporary RenderTexture RenderTexture.ReleaseTemporary(tmp); // "myTexture2D" now has the same pixels from "texture" and it's re
You can now get/set pixels from "myTexture2D".
More Information:
Comments
4 comments
Typo in your script:
// Create a new readable Texture2D to copy the pixels to it Texture2D myTexture2D = new Texture2D(texture.width, texture.width);
Above has "width" twice. Supposed to be:
new Texture2D(texture.width, texture.height);
Otherwise, it helped me a lot, thanks!
Fixed! thanks.
Very helpful, thanks.
Something I ran into afterwards; pixel coordinates for PC & iOS are different, as described here:
https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
https://docs.unity3d.com/ScriptReference/SystemInfo-graphicsUVStartsAtTop.html
Very helpful for Standalone and Android but hours of pain of debugging from iOS.
RenderTexture seems to be refreshed/cleared (Call it as you want) each time you call it from StandAlone and Android which let you use it for many texture in the same frame.
On iOS, you should call it once a frame or that will just render the first one called.
No idea why but the the per update trick is 100% working on iOS now.
Running with Unity 2019.3.0f1
Please sign in to leave a comment.