Search Unity

www.LoadImageIntoTexture and memory

Discussion in 'Scripting' started by CStocker, Dec 2, 2013.

  1. CStocker

    CStocker

    Joined:
    Jan 2, 2013
    Posts:
    3
    Hi,

    i'm trying to close all my memory leaks, so i wanted to clean up all my textures that get loaded with www.LoadImageIntoTexture. I know that this should be easy and i guess that has been asked quite often already.. i think it should also be somewhere in the documentation, BUT.. i can't find it :-(

    I have absolutly no idea what i need to do, to release the memory of a texture that was loaded with www.LoadImageIntoTexture. I tried several ways, searched the forums, but it seems its one of the days..

    Here's my code, which fills an NGUI UITexture with shiny pictures from the web

    Code (csharp):
    1.  
    2.   public static IEnumerator setExternalImageToUITexture(string path, UITexture ui_texture)
    3.   {    
    4.     Vector3 size = ui_texture.transform.localScale;
    5.     Texture2D tex = new Texture2D((int)size.x, (int)size.y, TextureFormat.ARGB32, false);
    6.  
    7.     WWW www = new WWW(path);
    8.     yield return www;
    9.    
    10.     www.LoadImageIntoTexture(tex);  
    11.     ui_texture.mainTexture = tex;
    12.   }  
    13.  
    So, any help would be appreciated
     
  2. HoMeBoYErik

    HoMeBoYErik

    Joined:
    Mar 12, 2014
    Posts:
    23
    I recently faced the same problem. I was creating an scrollable image gallery in Unity, where images are downloaded in real-time from the a web server. On iOS devices I was reaching very fast the memory limit (with consequent app crash). That was caused due to a very big number of www objects leaved in the memory and never deleted or released. Also a very big number of Texture2D objects leaked.
    The main misunderstanding is considering a Texture2D like a variable of an object that self-contained the image information. Texture2D only point to a referenced asset so we need to create one before assigning to our GUI object. Without creating one we will overwrite the referenced asset in our project, leading to very crazy behaviour.
    So this the code that works for me on iOS and just use the minimum of memory

    public void DownloadImage(string url)
    {
    StartCoroutine(coDownloadImage(url));
    }

    IEnumerator coDownloadImage(string imageUrl)
    {

    WWW www = new WWW( imageUrl );

    yield return www;

    thumbnail.mainTexture = new Texture2D(www.texture.width, www.texture.height, TextureFormat.DXT1, false);
    www.LoadImageIntoTexture(thumbnail.mainTexture as Texture2D);
    www.Dispose();
    www = null;
    }


    A brief comment:
    You receive a url you will download the image from.
    Start the coroutine that manage the download
    Create the www object in the local scope
    yield waiting the download to complete
    Create a new Texture2D object/asset with parameters and assign to your final object mainTexture or what do you want
    Use the "www.LoadImageIntoTexture()" function to COPY the image inside the created asset (this is the fundamental part)
    Dispose and set to null the www object to prevent memory leaking or orphans

    Hope it helps who will face the same problem.

    An interesting lecture is this website where they implement a WebImageCache system to avoid re-downloading the same image many times.

    http://studiofive27.com/index.php/unity-cached-web-images/
     
    guneyozsan likes this.