Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Save texture to disk after PackTexture

Discussion in 'Scripting' started by Rustam-Ganeyev, Mar 7, 2013.

  1. Rustam-Ganeyev

    Rustam-Ganeyev

    Joined:
    Jul 18, 2011
    Posts:
    29
    Hi! It's me again :)

    I have this texture save method:

    Code (csharp):
    1. public static void SaveTextureToFile(Texture2D texture, string fileName, bool highQuality = true)
    2.         {
    3.             byte[] bytes = texture.EncodeToPNG();
    4.             if (File.Exists(fileName)) File.Delete(fileName);
    5.             File.WriteAllBytes(fileName, bytes);
    6.         }
    Problem is texture.EncodeToPNG requires RGB32 texture format and if we do something like

    Code (csharp):
    1. atlasTexture.PackTextures(textures, atlasPadding, maxAtlasSize);
    2.         atlasMaterial.mainTexture = atlasTexture;
    3.         Utils.SaveTextureToFile(atlasTexture, Application.dataPath + "/testPic.png");
    it will throw an exception, because PackTextures packes to dxt5 format.

    So, question is: how to save atlas texture after PackTexture?
     
  2. willemsenzo

    willemsenzo

    Joined:
    Nov 15, 2012
    Posts:
    585
    Here is my implementation.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4.  
    5. public class TexturePacker : MonoBehaviour
    6. {
    7.     //Array which contains the textures to be packed  
    8.     public Texture2D[] textures = new Texture2D[4];
    9.    
    10.     public int textureSize = 4096;
    11.    
    12.     //Used to allow/disallow writing to PNG after texture packing
    13.     [HideInInspector]
    14.     public bool canGeneratePNG;
    15.    
    16.     //Used to give the output texture a name
    17.     public string nameForTexture;
    18.    
    19.     //Used to show preview of endresult
    20.     [HideInInspector]
    21.     public bool showPreview;   
    22.    
    23.     void Start()
    24.     {
    25.         //Check for empty texture slots
    26.         for (int i = 0; i < textures.Length; i++)
    27.         {
    28.             if (textures[i] == null)
    29.            
    30.                 print ("Texture " + i + " is not assigned");                   
    31.         }
    32.  
    33.     }
    34.    
    35.     void OnGUI()
    36.     {
    37.         //Used to give the output texture a name
    38.         nameForTexture = GUI.TextField(new Rect(10, 10, 200, 20), nameForTexture, 25);
    39.        
    40.         //Start texture packing if button is clicked and nameForTexture is set
    41.         if (GUI.Button (new Rect(10,50,200,200), "Generate Texture Atlas")  nameForTexture != "")
    42.         {
    43.             PackAllTextures();
    44.         }
    45.        
    46.         //When textures are done with packing this will be set to true
    47.         //A preview of the result will be shown
    48.         if (showPreview)
    49.         {
    50.             float previewWidth = renderer.material.mainTexture.width * 0.25f / 2.0f;
    51.             float previewHeight = renderer.material.mainTexture.height * 0.25f / 2.0f;
    52.             GUI.DrawTexture(new Rect((Screen.width/2)-250,(Screen.height/2)-250,previewWidth,previewHeight),renderer.material.mainTexture);
    53.         }
    54.        
    55.         //Toggle to allow writing to PNG when packing textures is done
    56.         if (GUI.Toggle(new Rect(10,30,200,20), canGeneratePNG, "Generate PNG"))
    57.         {
    58.             canGeneratePNG = true;
    59.         }
    60.        
    61.         //Toggle to disallow writing to PNG when packing textures is done
    62.         else if (GUI.Toggle(new Rect(10,30,200,20), canGeneratePNG, "Generate PNG"))
    63.         {
    64.             canGeneratePNG = false;
    65.         }      
    66.     }
    67.    
    68.     void PackAllTextures()     
    69.     {  
    70.         //Create new material with diffuse shading
    71.         //This material will hold the packed texture
    72.         Material newMaterial = new Material(Shader.Find("Diffuse"));
    73.        
    74.         //This new texture will contain all packed textures      
    75.         Texture2D packedTexture = new Texture2D(textureSize,textureSize);
    76.        
    77.         //Create a rect that stores all the textures UV's
    78.         //and pack them together into packedTexture
    79.         Rect[] uvs = packedTexture.PackTextures(textures,0,textureSize);
    80.        
    81.         //Set the new created material's main texture to the packed texture
    82.         newMaterial.mainTexture = packedTexture;
    83.        
    84.         //Apply the packed texture to the game object
    85.         renderer.material.mainTexture = packedTexture;
    86.        
    87.         //Allow preview of the result
    88.         showPreview = true;
    89.        
    90.         //Only execute when allowed in GUI
    91.         if (canGeneratePNG)
    92.         {
    93.             //Encode the packed texture to PNG
    94.             byte[] bytes = packedTexture.EncodeToPNG();
    95.        
    96.             //Save the packed texture to the datapath of your choice
    97.             File.WriteAllBytes(Application.dataPath + "/Textures/PackedTextures/" + nameForTexture + ".png", bytes);
    98.         }
    99.     }
    100. }
    101.        
    102.  
     
    Last edited: Mar 7, 2013
    ThinhHB likes this.