首页 > 解决方案 > 显示从服务器下载的多个图像

问题描述

我想下载已上传到服务器的多张图像,并在我的场景中的画廊或幻灯片中显示。我已经完成了下面的代码来下载图像,但我只能显示一张图像。如何显示从服务器下载的多个图像?

public void DownloadtheFiles()
    {

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

    for (int i = 0; i < photolist.Count; i++) {

        new GetUploadedRequest()

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

    public IEnumerator DownloadImages(string downloadUrl)
    {
        var www = new WWW(downloadUrl);
        yield return www;
        downloadedImages = new Texture2D(200, 200);
        www.LoadImageIntoTexture(downloadedImages);
        imageLoaded.texture = downloadedImages as Texture;
    }

更新 1:使用下面的代码,我展示了我想如何展示它们,但它从文件夹路径获取图像,我需要显示从服务器下载的图像。如何集成此代码以使用下载的图像制作幻灯片?

public class ImageLoader : MonoBehaviour
{
[SerializeField]
[Tooltip("The folder where images will be loaded from")]
private string imagePath;

[SerializeField]
[Tooltip("The panel where new images will be added as children")]
private RectTransform content;

private List<Texture2D> textures;

private void Start()
{
    Application.runInBackground = true;
    StartCoroutine(LoadImages());
}

public IEnumerator LoadImages()
{
    textures = new List<Texture2D>();

    DirectoryInfo di = new DirectoryInfo(imagePath);
    var files = di.GetFiles("*.png");

    foreach (var file in files)
    {
        Debug.Log(file.FullName);
        yield return LoadTextureAsync(file.FullName, AddLoadedTextureToCollection);
    }

    CreateImages();
}

private void AddLoadedTextureToCollection(Texture2D texture)
{
    textures.Add(texture);
}

private void CreateImages()
{
    foreach(var texture in textures)
    {
        GameObject imageObject = new GameObject("Image");
        imageObject.transform.SetParent(content);
        imageObject.AddComponent<Image>().sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
    }
}

public IEnumerator LoadTextureAsync(string originalFileName, Action<Texture2D> result)
{
    string fileToLoad = GetCleanFileName(originalFileName);

    Debug.Log("Loading Image from path: " + fileToLoad);

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

    Texture2D loadedTexture = new Texture2D(1, 1);

    www.LoadImageIntoTexture(loadedTexture);

    result(loadedTexture);
}

private static string GetCleanFileName(string originalFileName)
{
    string fileToLoad = originalFileName.Replace('\\', '/');

    if (fileToLoad.StartsWith("http") == false)
    {
        fileToLoad = string.Format("file://{0}", fileToLoad);
    }

    return fileToLoad;
}
}

更新 2:我创建了一个 ScrollView 和 Horizo​​natalLayoutGroup,并应用了更新 1 的 ImageLoader.cs。我在文件夹中添加了 4 个图像,这些是层次结构和结果的屏幕截图:

在此处输入图像描述

在此处输入图像描述

它作为测试工作正常,但图像的来源是我电脑中的一个文件夹,我想下载服务器的图像。我该怎么做?

标签: c#unity3d

解决方案


您已经使用ScrollView和完成了所有必需的部分HorizonatalLayoutGroup。请注意,我要求您使用该RawImage组件,但您似乎正在使用该Image组件。我推荐RawImage是因为让你避免使用Sprite.Create昂贵的东西。Image如果你愿意,你仍然可以使用。

你现在唯一要做的就是调整它的大小,RawImage直到你对它的大小感到满意为止。从中创建一个预制件RawImage。删除 Content GameObject 下的 Image/RawImage。你不再需要它们了。

现在,从服务器下载您的图像,从该 RawImage 预制件中实例化一个预制件。最后,让它RawImage成为 Content GameObject 的子对象。而已。HorizonatalLayoutGroup应该自动定位它。

使用您的原始代码,以下是如何做到这一点。该contentRef变量是对 ScrollView 下的 Content GameObject 的引用。该imgPrefab变量是对RawImage预制件的引用。确保从编辑器分配两者。另外,请注意我如何添加和使用新变量int index = i;来防止捕获i变量并导致它只下载最后一个图像。

public GameObject contentRef;
public RawImage imgPrefab;

void Start()
{
    DownloadtheFiles();
}

public void DownloadtheFiles()
{

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

    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));
            });
    }
}


public IEnumerator DownloadImages(string downloadUrl, int index)
{
    var www = new WWW(downloadUrl);
    yield return www;

    //Instantiate the image prefab GameObject and make it a child of the contentRef
    RawImage newImg = Instantiate(imgPrefab, contentRef.transform);
    //Change the name
    newImg.name = "Image-" + index;

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

    //Apply the downloaded image
    newImg.texture = tex;
}

推荐阅读