加载图像表单 PersistenceDataPath

我正在制作一个 Android 应用程序,它应该在开始时从 MySQL 数据库加载数据和从服务器加载一些图像。之后,用户将在外面,因此应用程序将离线工作。


我编写了代码以将所有数据库数据(有效)和图像从服务器保存到 ApplicationPersistenceDataPath(无效)。我已经在寻找我应该怎么做。我的代码不会引发任何错误。但是,当我尝试在应用程序上显示它时,图像是空白的。那是当我查看存储图像的文件夹时,我无法打开它们。


这是我必须保存图像的方法:


IEnumerator loadBgImage(string url, string file_name)

    {

        using (UnityWebRequest www = UnityWebRequest.Get(url))

        {

            yield return www.Send();

            if (www.isNetworkError || www.isHttpError)

            {

                print("erro");

            }

            else

            {

                string savePath = string.Format("{0}/{1}", Application.persistentDataPath, file_name);

                if (!File.Exists(savePath))

                {

                    System.IO.File.WriteAllText(savePath, www.downloadHandler.text);

                }

            }

        }

    }

这是在图像中显示图像文件的代码:


string path = Application.persistentDataPath + "/" + nomeImagem;

imagem.GetComponent<SpriteRenderer>().sprite = LoadSprite(path);

这是称为的方法:


    private Sprite LoadSprite(string path)

    {

        if (string.IsNullOrEmpty(path)) return null;

        if (System.IO.File.Exists(path))

        {            

            byte[] bytes = File.ReadAllBytes(path);

            Texture2D texture = new Texture2D(900, 900, TextureFormat.RGB24, false);

            texture.filterMode = FilterMode.Trilinear;

            texture.LoadImage(bytes);

            Sprite sprite = Sprite.Create(texture, new Rect(0, 0, 8, 8), new Vector2(0.5f, 0.0f), 1.0f);


        }

        return null;

    }

我真的需要先保存图像,然后离线显示。有人可以告诉我我做错了什么吗?



SMILET
浏览 110回答 1
1回答

炎炎设计

一般来说,你应该宁愿使用Path.Combinelikevar path = Path.Combine(Application.persistentDataPath, FileName);代替系统路径!可能是您的目标设备根本不理解/为路径分隔符。如果文件已经存在(也许是更新的版本?而且你已经下载了它)也可以写,或者如果它已经存在你甚至不应该开始下载以节省带宽。我还认为这WriteAllText不是二进制图像数据的正确解决方案,因为www.downloadHandler.text已经解释为 UTF8 字符串因此,由于图像很可能有一些字节在 UTF8 字符串中无法表示,因此您会在此处获得损坏的数据!你宁愿直接使用www.downloadHandler.data它返回原始byte[]而不是例如File.WriteAllBytes(仅在UWP上)或将其FileStream写入byte[]文件的正确方法。就像是var data = www.downloadHandler.data;File.WriteAllBytes(path, data);或者var data = www.downloadHandler.data;using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write)){&nbsp; &nbsp; fs.Write(data, 0, data.Length);}比场景中的白色图像通常意味着精灵是null.如果没有打字错误,那么您LoadSprite 总是returns null。你忘了归还创建的spriteprivate Sprite LoadSprite(string path){&nbsp; &nbsp; if (string.IsNullOrEmpty(path)) return null;&nbsp; &nbsp; if (System.IO.File.Exists(path))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; byte[] bytes = File.ReadAllBytes(path);&nbsp; &nbsp; &nbsp; &nbsp; Texture2D texture = new Texture2D(900, 900, TextureFormat.RGB24, false);&nbsp; &nbsp; &nbsp; &nbsp; texture.filterMode = FilterMode.Trilinear;&nbsp; &nbsp; &nbsp; &nbsp; texture.LoadImage(bytes);&nbsp; &nbsp; &nbsp; &nbsp; Sprite sprite = Sprite.Create(texture, new Rect(0, 0, 8, 8), new Vector2(0.5f, 0.0f), 1.0f);&nbsp; &nbsp; &nbsp; &nbsp; // You should return the sprite here!&nbsp; &nbsp; &nbsp; &nbsp; return sprite;&nbsp; &nbsp; }&nbsp; &nbsp; return null;}但是请注意,加载本地图像的更好方法实际上UnityWebRequestTexture也是如此。它还将本地文件路径作为 URL 和与下载原始字节并在脚本中手动创建纹理相比,使用此类可显着减少内存重新分配。此外,纹理转换将在工作线程上执行。但是也仅支持 JPG 和 PNG 格式。但这不应该是我想的问题,因为LoadImage到目前为止您使用的也是相同限制的基础。但是,这将是异步的,因此您必须等待纹理才能创建精灵。因此,与其重新调整,Sprite我实际上宁愿传入相应Image组件的引用并直接替换其sprite. 就像是private IEnumerator LoadLocalTexture(string path, Image receivingImage){&nbsp; &nbsp; UnityWebRequest www = UnityWebRequestTexture.GetTexture(path);&nbsp; &nbsp; yield return www.SendWebRequest();&nbsp; &nbsp; if(www.isNetworkError || www.isHttpError)&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Debug.Log(www.error);&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var texture = ((DownloadHandlerTexture)www.downloadHandler).texture;&nbsp; &nbsp; &nbsp; &nbsp; var sprite = Sprite.Create(texture, new Rect(0, 0, 8, 8), new Vector2(0.5f, 0.0f), 1.0f);&nbsp; &nbsp; &nbsp; &nbsp; receivingImage.sprite = sprite;&nbsp; &nbsp; }}如果您实际上并不一定要使用,Sprites我总是建议您RawImage改用可以直接使用的组件Texture2D!而不是做类似的事情private IEnumerator LoadLocalTexture(string path, RawImage receivingImage){&nbsp; &nbsp; UnityWebRequest www = UnityWebRequestTexture.GetTexture(path);&nbsp; &nbsp; yield return www.SendWebRequest();&nbsp; &nbsp; if(www.isNetworkError || www.isHttpError)&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; Debug.Log(www.error);&nbsp; &nbsp; }&nbsp; &nbsp; else&nbsp;&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var texture = ((DownloadHandlerTexture)www.downloadHandler).texture;&nbsp; &nbsp; &nbsp; &nbsp; receivingImage.texture = texture;&nbsp; &nbsp; }}但是也注意:请记住,使用 RawImage 会在每个 RawImage 出现时创建一个额外的绘制调用,因此最好仅将其用于背景或临时可见图形。
打开App,查看更多内容
随时随地看视频慕课网APP