Lee David
Lee David

Reputation: 33

How can I load local images asynchronously?

I want to load a local image asynchronously, but "sprite.create" takes so much time which make my UI stop. How can I fix this?

WWW www = new WWW (filePath);
    yield return www;

    Texture2D texture = new Texture2D(4, 4, TextureFormat.ARGB32, true);
    www.LoadImageIntoTexture(texture);
    www.Dispose ();
    www = null;

    curTexture = texture;
    img.sprite = Sprite.Create (curTexture, new Rect (0, 0, curTexture.width, curTexture.height), new Vector2 (0.5f, 0.5f));

Update 2016.08.26:

I used RawImage to set texture instead of using Image which need to change texture to sprite.

Another question is that www.LoadImageIntoTexture is also take so much time. I used www.texture before, but I found it failed to load some png from android device which just display a blue image.

Upvotes: 2

Views: 2412

Answers (2)

JeanLuc
JeanLuc

Reputation: 4903

As stated in my comment I would recommend using RawImage, which has a texture property, so you don't need to create a Sprite.

[SerializeField] private RawImage _rawImage;

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

private IEnumerator DownloadImageCoroutine(string url)
{
    using (WWW www = new WWW(url))
    {
        // download image
        yield return www;

        // if no error happened
        if (string.IsNullOrEmpty(www.error))
        {
            // get texture from WWW
            Texture2D texture = www.texture;

            yield return null; // wait a frame to avoid hang

            // show image
            if (texture != null && texture.width > 8 && texture.height > 8)
            {
                _rawImage.texture = texture;
            }
        }
    }
}

Upvotes: 2

Cabrra
Cabrra

Reputation: 644

Call a coroutine using this:

StartCoroutine(eImageLoad(filepath));

And here is the definition:

IEnumerator eImageLoad(string path)
{
    WWW www = new WWW (path);

    //As @ Scott Chamberlain suggested in comments down below
    yield return www;

    //This is longer but more explanatory
    //while (false == www.isDone)
    //{
    //    yield return null;
    //}

    //As @ Scott Chamberlain suggested in comments you can get the texture directly

    curTexture = www.Texture;

    www.Dispose ();
    www = null;

    img.sprite = Sprite.Create (curTexture, new Rect (0, 0, curTexture.width, curTe
}

Upvotes: 1

Related Questions