Create / Modify Texture2D to Read/Write Enabled at Runtime

How can I create or edit a texture, at runtime, with its read/write property enabled? The TextureFormat doesn’t seem to help, and I can’t find out how to make it work.

Note: TextureImporter and AssetDatabase don’t work. They require the UnityEditor namespace, and that doesn’t work in an exported build (I’m making this for iOS).

In the editor, you can just set a texture’s type to Advanced and set its Read/Write Enabled property to true, but of course I don’t have access to the editor at runtime.

Thanks!

4 Answers

4

From here : c# - How to make Texture2D Readable via script - Stack Overflow
@nyonge , i got this, and it worked well for me :

Texture2D duplicateTexture(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;
}

this code saved my ASS :) well done!

–

My texture is blank when I use this method. Do you how to fix that?

–

“Readonly” only applies to assets that you import at edittime. So if you imported a texture at edittime and you didn’t make it readable, you can’t read it at runtime and you can’t make it readable. So if you need textures which you imported in the editor readable at runtime you have to mark it as readable inside the editor.

Textures created at runtime are always readable unless you pass “true” as second parameter to Apply in which case you made the texture none-readable forever just like an asset that never was.

If you load images at runtime from external sources they also are readable by default

I had a similar issue, and found out why created then saved Texture2D’s weren’t readable after the fact. It’s because once you save it, it saves the texture as “Default”, which default has Read/Write disabled. Edited: I have fixed my original code, it now works!

Texture2D colorPalette = new Texture2D(8, 8);
colorPalette.SetPixels32(gameColors);
colorPalette.Apply(); 
print($"created texture is readable: {colorPalette.isReadable}"); // true

string path = "/MapTextures/";
string fileName = "test03.png";
byte[] bytes = colorPalette.EncodeToPNG();
System.IO.File.WriteAllBytes(Application.dataPath + path + fileName, bytes);
AssetDatabase.SaveAssets(); 
AssetDatabase.Refresh();

Texture2D savedFile = (Texture2D)AssetDatabase.LoadAssetAtPath(
    "Assets" + path + fileName, 
    typeof(Texture2D));
// error: NullReferenceException: FIXED!!!
print($"saved file is readable: {savedFile.isReadable}"); // false
  
TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(
    "Assets" + path + fileName);
importer.isReadable = true;
AssetDatabase.ImportAsset(
    "Assets" + path + fileName, 
    ImportAssetOptions.ForceUpdate);
print($"saved file is readable: {savedFile.isReadable}"); // true

Edited: NullReferenceException was fixed because I had to call “SaveAssets()” then add in “Refresh()”, and now it works within one call during one runtime! :smiley:

If you want to make something readable, you’d best create a new readable texture at runtime.

If you want to make a read/write texture “static”, use: Unity - Scripting API: Texture2D.Apply