以快速方式显示从服务器下载的图像

时间:2018-05-17 10:49:16

标签: c# unity3d

我有一个场景,我想要显示从服务器下载的多个图像。我正在尝试下载纹理并将它们存储在List中。当for循环完成运行时,我按名称对List进行排序,然后从List中实例化RawImage,但不起作用。我做错了什么?

public GameObject contentRef;
public RawImage imgPrefab;

void Start()
{
    StartCoroutine(DownloadtheFiles());
}

public IEnumerator DownloadtheFiles()
{
    yield return null;

    List<string> photolist = ES2.LoadList<string>("myPhotos.txt");

    for (int i = 0; i < photolist.Count; i++)
    {
        //Don't capture i variable
        int index = i;

        bool reqDone = false;

        new GetUploadedRequest()

            .SetUploadId(photolist[index])
            .Send((response) =>
                {
                    StartCoroutine(DownloadImages(response.Url, index,
                        (status) => { reqDone = status; }));


                    //return null;
                });

        //Wait in the for loop until the current request is done
        while (!reqDone)
            yield return null;
    }
}

public IEnumerator DownloadImages(string downloadUrl, int index, Action<bool> done)
{
    var www = new WWW(downloadUrl);
    yield return www;

    //Get the downloaded image
    Texture2D tex = new Texture2D(4, 4);
    www.LoadImageIntoTexture(tex);

    List <Texture2D> texList = new List <Texture2D> ();

    for (int i = 0; i < tex.Count; i++)
    {
        texList.Add (tex);
    }

    texList = texList.OrderBy(mtex => mtex.name).ToList();

    for (int i = 0; i < tex.Count; i++)
    {
        RawImage newImg = Instantiate(imgPrefab, contentRef.transform);
        //Change the name
        newImg.name = "Image-" + index;
        //Apply the downloaded image
        newImg.texture = tex;
    }

    //Done
    if (done != null)
        done(true);
}

}

1 个答案:

答案 0 :(得分:1)

您的RawImage代码应在DownloadImages函数之外完成,因为DownloadImages被调用以从for循环中的网址下载图片。 RawImage实例化应该仅在for循环完成后才能完成。

另外,使用texList.OrderBy(mtex => mtex.name).ToList();不会起作用,因为你的字符串包含字符串和int,并且格式为&#34; Image - &#34; + 0;&#34; 。您需要使用自定义函数来分割stringint,然后使用int进行排序。

最后,在for循环运行完毕后,您需要一种方法来确定在实例化RawImages之前所有图像都已完成下载。您可以使用包含要下载的图像链接的bool大小的List<string> photolist数组或列表来执行此操作。将该bool数组传递给DownloadImages,并在每次下载完成后使用index参数将其设置为true

public GameObject contentRef;
public RawImage imgPrefab;

List<Texture2D> downloadedTextures = new List<Texture2D>();

void Start()
{
    DownloadtheFiles();
}

public void DownloadtheFiles()
{

    List<string> photolist = ES2.LoadList<string>("myPhotos.txt");

    //Used to determine when were done downloading
    bool[] doneDownloading = new bool[photolist.Count];

    //Download images only.Don't instantiate anything
    for (int i = 0; i < photolist.Count; i++)
    {
        //Don't capture i variable
        int index = i;

        new GetUploadedRequest()

            .SetUploadId(photolist[index])
            .Send((response) =>
            {
                StartCoroutine(DownloadImages(response.Url, index, doneDownloading));
            });
    }

    //Instantiate the download images
    StartCoroutine(InstantiateImages(doneDownloading));
}

//Instantiates the downloaded images after they are done downloading
IEnumerator InstantiateImages(bool[] downloadStatus)
{
    //Wait until all images are done downloading
    for (int i = 0; i < downloadStatus.Length; i++)
    {
        while (!downloadStatus[i])
            yield return null;
    }

    //Sort the images by string
    sort(ref downloadedTextures);

    //Now, instantiate the images
    for (int i = 0; i < downloadedTextures.Count; i++)
    {
        //Instantiate the image prefab GameObject and make it a child of the contentRef
        RawImage newImg = Instantiate(imgPrefab, contentRef.transform);

        //Apply the downloaded image
        newImg.texture = downloadedTextures[i];

        //Update name so that we can see the names in the Hierarchy
        newImg.name = downloadedTextures[i].name;
    }

    //Clear List for next use
    downloadedTextures.Clear();
}

//Sort the downloaded Textures by name
void sort(ref List<Texture2D> targetList)
{
    var ordered = targetList.Select(s => new { s, Str = s.name, Split = s.name.Split('-') })
    .OrderBy(x => int.Parse(x.Split[1]))
    .ThenBy(x => x.Split[0])
    .Select(x => x.s)
    .ToList();

    targetList = ordered;
}

public IEnumerator DownloadImages(string downloadUrl, int index, bool[] downloadStatus)
{
    //Download image
    var www = new WWW(downloadUrl);
    yield return www;

    //Get the downloaded image and add it to the List
    Texture2D tex = new Texture2D(4, 4);
    //Change the name
    tex.name = "Image-" + index;
    www.LoadImageIntoTexture(tex);
    downloadedTextures.Add(tex);

    downloadStatus[index] = true;
}