Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  4. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  5. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  6. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Generating sprites dynamically from PNG or JPEG files in C#

Discussion in 'Scripting' started by c68, Jul 26, 2015.

  1. c68

    c68

    Joined:
    Jul 10, 2013
    Posts:
    4
    Hey everyone!

    I was searching the forums here (and some external sources) to find a way to load an external PNG file into a Unity-Sprite and display it on a UI.image element. It took me about a day to figure out how to do this! :-o

    But i finally managed to do it and thought its about time to give back something to the forum and share this little class with you.

    Hope this helps in any way in case you are looking for the same info as I did! :)

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.IO;
    4.  
    5. public class IMG2Sprite : MonoBehaviour {
    6.  
    7.    // This script loads a PNG or JPEG image from disk and returns it as a Sprite
    8.    // Drop it on any GameObject/Camera in your scene (singleton implementation)
    9.    //
    10.    // Usage from any other script:
    11.    // MySprite = IMG2Sprite.instance.LoadNewSprite(FilePath, [PixelsPerUnit (optional)])
    12.  
    13.    private static IMG2Sprite _instance;
    14.  
    15.    public static IMG2Sprite instance
    16.    {
    17.      get    
    18.      {
    19.        //If _instance hasn't been set yet, we grab it from the scene!
    20.        //This will only happen the first time this reference is used.
    21.  
    22.        if(_instance == null)
    23.          _instance = GameObject.FindObjectOfType<IMG2Sprite>();
    24.        return _instance;
    25.      }
    26.    }
    27.  
    28.    public Sprite LoadNewSprite(string FilePath, float PixelsPerUnit = 100.0f) {
    29.    
    30.      // Load a PNG or JPG image from disk to a Texture2D, assign this texture to a new sprite and return its reference
    31.      
    32.      Sprite NewSprite = new Sprite();
    33.      Texture2D SpriteTexture = LoadTexture(FilePath);
    34.      NewSprite = Sprite.Create(SpriteTexture, new Rect(0, 0, SpriteTexture.width, SpriteTexture.height),new Vector2(0,0), PixelsPerUnit);
    35.  
    36.      return NewSprite;
    37.    }
    38.  
    39.    public Texture2D LoadTexture(string FilePath) {
    40.  
    41.      // Load a PNG or JPG file from disk to a Texture2D
    42.      // Returns null if load fails
    43.  
    44.      Texture2D Tex2D;
    45.      byte[] FileData;
    46.  
    47.      if (File.Exists(FilePath)){
    48.        FileData = File.ReadAllBytes(FilePath);
    49.        Tex2D = new Texture2D(2, 2);           // Create new "empty" texture
    50.        if (Tex2D.LoadImage(FileData))           // Load the imagedata into the texture (size is set automatically)
    51.          return Tex2D;                 // If data = readable -> return texture
    52.      }  
    53.      return null;                     // Return null if load failed
    54.    }
    55. }
    Happy Coding!
     
  2. IKStreamIvo

    IKStreamIvo

    Joined:
    Nov 16, 2015
    Posts:
    2
    Many, many, many thanks!
     
  3. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,103
    just fyi, LoadImage has a big "thunk" to it to decode either PNG or JPG for textures... you should really look into using native formats for the images like DDS or PVR and use LoadRawTextureData (with their respective headers removed from the bits).
     
  4. TutiBueno2

    TutiBueno2

    Joined:
    Oct 16, 2012
    Posts:
    3
    Thanks it helped a lot!
     
  5. CloudWeight

    CloudWeight

    Joined:
    Jul 16, 2014
    Posts:
    168
    I found it much more efficient (for my use at least) to drop it into a static tools class and be able to reference it anywhere without having to drop it in the scene constantly. I also added SpriteMeshType so that you can choose (optional) whether to use Tight or FullRect. Unity likes to load FullRect faster than Tight so it might be use to some people for testing or real world use purposes. Just drop this into any script file and it will work outright :)

    Edit 2/9/2018: I added a simple conversion method to the IMG2Sprite class since I needed to convert Texture2D's that are already loaded.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.IO;
    5.  
    6. public static class IMG2Sprite
    7. {
    8.  
    9.     //Static class instead of _instance
    10.     // Usage from any other script:
    11.     // MySprite = IMG2Sprite.LoadNewSprite(FilePath, [PixelsPerUnit (optional)], [spriteType(optional)])
    12.  
    13.     public static Sprite LoadNewSprite(string FilePath, float PixelsPerUnit = 100.0f, SpriteMeshType spriteType = SpriteMeshType.Tight)
    14.     {
    15.  
    16.         // Load a PNG or JPG image from disk to a Texture2D, assign this texture to a new sprite and return its reference
    17.  
    18.         Sprite NewSprite = new Sprite();
    19.         Texture2D SpriteTexture = LoadTexture(FilePath);
    20.         NewSprite = Sprite.Create(SpriteTexture, new Rect(0, 0, SpriteTexture.width, SpriteTexture.height), new Vector2(0, 0), PixelsPerUnit, 0 , spriteType);
    21.  
    22.         return NewSprite;
    23.     }
    24.  
    25.     public static Sprite ConvertTextureToSprite(Texture2D texture, float PixelsPerUnit = 100.0f, SpriteMeshType spriteType = SpriteMeshType.Tight)
    26.     {
    27.         // Converts a Texture2D to a sprite, assign this texture to a new sprite and return its reference
    28.  
    29.         Sprite NewSprite = new Sprite();
    30.         NewSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0), PixelsPerUnit, 0, spriteType);
    31.  
    32.         return NewSprite;
    33.     }
    34.  
    35.     public static Texture2D LoadTexture(string FilePath)
    36.     {
    37.  
    38.         // Load a PNG or JPG file from disk to a Texture2D
    39.         // Returns null if load fails
    40.  
    41.         Texture2D Tex2D;
    42.         byte[] FileData;
    43.  
    44.         if (File.Exists(FilePath))
    45.         {
    46.             FileData = File.ReadAllBytes(FilePath);
    47.             Tex2D = new Texture2D(2, 2);           // Create new "empty" texture
    48.             if (Tex2D.LoadImage(FileData))           // Load the imagedata into the texture (size is set automatically)
    49.                 return Tex2D;                 // If data = readable -> return texture
    50.         }
    51.         return null;                     // Return null if load failed
    52.     }
    53. }
    54.  
     
    Last edited: Feb 10, 2018
    twobob, mischinab and Arctous like this.
  6. mischinab

    mischinab

    Joined:
    Nov 30, 2016
    Posts:
    1
    You can also use Resources.Load to create a sprite, if you have the image file in your Resources folder:

    string path = "filename"; // filename.png should be stored in your Assets/Resources folder
    Sprite sprite = Resources.Load<Sprite>(path);


    This is handy if you have a collection of images, and want to be able to choose one dynamically by filename at runtime.
     
  7. Hamid-Gh

    Hamid-Gh

    Joined:
    Feb 16, 2018
    Posts:
    2
    can you show me how to use the script ?