快速显示从服务器下载的图像 [英] Show images downloaded from a server in a fast way
问题描述
我有一个场景,我想显示从服务器下载的多个图像.我正在尝试下载纹理并将其存储在列表中.当for循环完成运行时,我按名称对列表进行排序,然后从列表中实例化RawImage,但不起作用.我在做什么错了?
I have a scene where I'd like to show multiple images downloaded from a server. I'm trying to download the textures and store them in a List. When the for loop finish running, I sort the List by name and then I instantiate the RawImage from the List, but doesn't works. What am I doing wrong?
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);
}
}
推荐答案
您的RawImage
代码应在DownloadImages
函数外部完成,因为调用DownloadImages
是为了从for
循环中的URL下载图像. RawImage
实例化应仅在for
循环完成之后进行.
Your RawImage
code should be done outside the DownloadImages
function because DownloadImages
is called to download image from the url in the for
loop. The RawImage
instantiation should be done only after the for
loop has completed.
此外,使用texList.OrderBy(mtex => mtex.name).ToList();
也不起作用,因为您的字符串同时包含string和int且格式为"Image-" + 0;".您将需要一个自定义函数来执行此操作通过拆分string
和int
然后用int
排序.
Also, using texList.OrderBy(mtex => mtex.name).ToList();
wouldn't work because your string contains both string and int and is in this format "Image-" + 0;". You will need a custom function to do that by splitting the string
and int
then sorting with the int
.
最后,在for
循环完成运行之后,需要一种方法来实例化RawImages
之前确定所有映像均已完成下载.您可以通过使用数组或bool
的列表来实现此目的,其中List<string> photolist
的大小应包含要下载的图像链接.每次下载完成后,将该布尔数组传递给DownloadImages
并使用index
参数将其设置为true
.
Finally, after the for
loop has finished running, you need a way to determine that all images has finished downloading before instantiating the RawImages
. You can do this by using array or List of bool
with the size of the List<string> photolist
that contains the link of images to download. Pass that array of bool to the DownloadImages
and use the index
argument to set it to true
when each download is done.
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;
}
这篇关于快速显示从服务器下载的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!