Unity使用C#網路下載使用者頭像
阿新 • • 發佈:2018-12-15
Unity使用C#網路下載使用者頭像
其實每個人中都會遇到在專案下載使用者頭像,下面是專案中使用的網路下載圖片,使用WWW從網路上下載到本地,本地獲取圖片,使用的Unity版本是2017.1,使用UGUI
封裝UnityEngine.WWW進行下載的類DownloadWWW .cs
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Xml; using System.Linq; using UnityEngine; /// <summary> /// 封裝UnityEngine.WWW進行下載的類 /// </summary> public class DownloadWWW : MonoBehaviour { private static DownloadWWW instance; public static DownloadWWW Instance { get { if (instance == null) { GameObject obj = new GameObject(); //obj.name = "DownloadWWW"; instance = obj.AddComponent<DownloadWWW>(); } return instance; } } private void Awake() { DontDestroyOnLoad(gameObject); } /// <summary> /// 下載url資源的文字內容 /// </summary> /// <param name="url">url資源</param> /// <param name="isAddRandomParams">是否新增隨機引數</param> /// <param name="callback">下載完畢回撥函式</param> /// <param name="retryCount">本次下載失敗後的重試次數</param> public void DownloadText(string url, bool isAddRandomParams, Action<bool, string> callback, Action<float> progress, int retryCount) { if (isAddRandomParams) url = GetRandomParamsUrl(url); Debug.Log("URL:" + url); StartCoroutine(DoDownloadText(url, callback, progress, retryCount)); } private IEnumerator DoDownloadText(string url, Action<bool, string> callback, Action<float> progress, int retryCount) { var www = new WWW(url); while (!www.isDone) { if (progress != null) progress(www.progress); yield return null; } if (progress != null) progress(www.progress); if (string.IsNullOrEmpty(www.error)) { if (callback != null) callback(true, www.text); } else { if (retryCount <= 0) { // 徹底失敗 Debug.LogError(string.Concat("DownloadText Failed! URL: ", url, ", Error: ", www.error)); if (callback != null) callback(false, null); } else { // 繼續嘗試 yield return StartCoroutine(DoDownloadText(url, callback, progress, --retryCount)); } } } /// <summary> /// 下載url資源的位元組內容 /// </summary> /// <param name="url">url資源</param> /// <param name="isAddRandomParams">是否新增隨機引數</param> /// <param name="callback">下載完畢回撥函式</param> /// <param name="retryCount">本次下載失敗後的重試次數</param> public void DownloadBytes(string url, bool isAddRandomParams, Action<bool, byte[]> callback, Action<float> progress, int retryCount) { if (isAddRandomParams) url = GetRandomParamsUrl(url); Debug.Log("URL:" + url); StartCoroutine(DoDownloadBytes(url, callback, progress, retryCount)); } private IEnumerator DoDownloadBytes(string url, Action<bool, byte[]> callback, Action<float> progress, int retryCount) { var www = new WWW(url); while (!www.isDone) { if (progress != null) progress(www.progress); yield return null; } if (progress != null) progress(www.progress); if (string.IsNullOrEmpty(www.error)) { if (callback != null) callback(true, www.bytes); } else { if (retryCount <= 0) { // 徹底失敗 Debug.LogError(string.Concat("DownloadBytes Failed! URL: ", url, ", Error: ", www.error)); if (callback != null) callback(false, null); } else { // 繼續嘗試 yield return StartCoroutine(DoDownloadBytes(url, callback, progress, --retryCount)); } } } /// <summary> /// 給原始url加上隨機引數 /// </summary> /// <param name="url"></param> /// <returns></returns> private string GetRandomParamsUrl(string url) { var r = new System.Random(); var u = string.Format("{0}?type={1}&ver={2}&sign={3}", url.Trim(), r.Next(100), r.Next(100), Guid.NewGuid().ToString().Substring(0, 8)); return u; } /// <summary> /// 訪問http /// </summary> /// <param name="url"></param> /// <param name="onDone"></param> /// <param name="onFail"></param> public void GetHttp(string url, Action<string> onDone, Action<string> onFail) { Debug.Log("URL:" + url); StartCoroutine(DoGetHttp(url, onDone, onFail)); } private IEnumerator DoGetHttp(string url, Action<string> onDone, Action<string> onFail) { WWW www = new WWW(url); yield return www; if (string.IsNullOrEmpty(www.error)) { onDone(www.text); } else { Debug.Log("HttpResponse onFail:" + www.error); onFail(www.error); } } }
HTTP下載HttpManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.IO; using System; using System.Text; using UnityEngine.UI; /// <summary> /// HTTP下載 /// </summary> public class HttpManager : MonoBehaviour { private static HttpManager instance; public static HttpManager Instance { get { if (instance == null) { GameObject obj = new GameObject(); obj.name = "HttpManager"; instance = obj.AddComponent<HttpManager>(); } return instance; } } /// <summary> /// web下載物體 /// </summary> private GameObject webDownloaderObj; /// <summary> /// 下載類 /// </summary> private DownloadWWW downloadWWW; /// <summary> /// 快取字典 /// </summary> private Dictionary<string, Texture2D> dicHeadTextureMd5; /// <summary> /// 下載的圖相list /// </summary> private List<string> lisHeadName;//預備下載影象清單 //private void Awake() //{ //} void Start () { Init(); } public void Init() { webDownloaderObj = new GameObject("WebDownloader"); downloadWWW = webDownloaderObj.AddComponent<DownloadWWW>(); dicHeadTextureMd5 = new Dictionary<string, Texture2D>(); } /// <summary> /// 手機記憶體讀取圖片 /// </summary> public Texture2D LoadTexture2DInStorage(string url) { //建立檔案讀取流 FileStream fileStream = new FileStream(url, FileMode.Open, FileAccess.Read); fileStream.Seek(0, SeekOrigin.Begin); //建立檔案長度緩衝區 byte[] bytes = new byte[fileStream.Length]; //讀取檔案 fileStream.Read(bytes, 0, (int)fileStream.Length); //釋放檔案讀取流 fileStream.Close(); fileStream.Dispose(); fileStream = null; //建立Texture int width = 50; int height = 50; Texture2D texture = new Texture2D(width, height, TextureFormat.RGB24, false); texture.LoadImage(bytes); return texture; } /// <summary> /// 字典初始化 /// </summary> private void InitTempTextture() { if (dicHeadTextureMd5 == null) { dicHeadTextureMd5 = new Dictionary<string, Texture2D>(); } } /// <summary> /// 清單初始化 /// </summary> private void InitTempLisName() { if (lisHeadName == null) lisHeadName = new List<string>(); } /// <summary> /// 檢測字典是否包含該圖片 /// </summary> /// <param name="textureName"></param> /// <returns></returns> public bool IshaveTempTextture(string textureName) { return (dicHeadTextureMd5.ContainsKey(textureName)); } /// <summary> /// 臨時儲存圖片到字典 /// </summary> /// <param name="textureName"></param> /// <param name="texture2D"></param> public void SaveTempDicTextture(string textureName, Texture2D texture2D) { if (!dicHeadTextureMd5.ContainsKey(textureName)) dicHeadTextureMd5.Add(textureName, texture2D); } /// <summary> /// 從字典讀取圖片 /// </summary> /// <param name="textureName"></param> /// <returns></returns> public Texture2D LoadTempDicTextture(string textureName) { return dicHeadTextureMd5[textureName]; } /// <summary> /// 載入預設頭像,並存入字典(臨時儲存) /// </summary> /// <returns></returns> public Texture2D LoadDefaultTexture(string texNameMd5) { Texture2D defTex = Resources.Load<Texture2D>("Face/headdefault");//載入預設頭像 SaveTempDicTextture(texNameMd5, defTex);//存入字典(臨時儲存) return defTex; } public void LoadImage(string url,GameObject path) { RawImage rawImage = path.GetComponent<RawImage>(); if (rawImage != null) { StartCoroutine(LoadHead(url, rawImage)); } } /// <summary> /// 頭像載入 /// </summary> /// <param name="url"></param> /// <returns></returns> public IEnumerator LoadHead(string url, RawImage logo) { int tryCount = 0; while (tryCount < 10)//下載嘗試次數 { bool andios = (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer); string texName = url;//圖片名稱.Remove(0, url.LastIndexOf("/") + 1) string texNameMd5 = RegularExpression.MD5Encrypt32(texName);//圖片名稱加密md5 //Debug.Log(texName + " " + texNameMd5);+ string directoryPath = "";//圖片資料夾路徑 string directoryMd5Path = "";//圖片檔案完整路徑 bool isLoad = false;//是否開始下載,否則讀記憶體 InitTempTextture(); InitTempLisName();//初始化清單 if (!lisHeadName.Contains(texNameMd5)) { lisHeadName.Add(texNameMd5); isLoad = true;//不存在則新增入清單,並進入下載模式 } yield return 0;//下一幀後檢測全域性 if (!isLoad) { float waitTime = 0; while (!IshaveTempTextture(texNameMd5) && waitTime < 1.5f) { waitTime += Time.deltaTime; yield return 0; }//字典是否含該圖片,等待快出現的記憶體 if (waitTime < 1.5f) { if(logo) logo.texture = LoadTempDicTextture(texNameMd5);//顯示//有則直接讀取記憶體 } else logo.texture = LoadDefaultTexture(texNameMd5); tryCount = 10; break;//結束 } else { //無則開始圖片載入過程 if (andios) { ///手機無則建立資料夾 //directoryPath = "D:/" + "/headimage";// directoryPath = Application.persistentDataPath + "/headimage";//資料夾路徑 Debug.Log("<color=yellow>圖片儲存路徑:::"+ directoryPath + "</color>"); if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);//無則建立資料夾 while (!Directory.Exists(directoryPath)) { yield return 0; }//建立時間,檢測資料夾是否存在 directoryMd5Path = directoryPath + "/" + texNameMd5;//圖片檔案完整路徑 //讀取手機記憶體中資料夾裡的圖片 if (File.Exists(directoryMd5Path)) { Debug.Log("匯入手機記憶體圖片"); Texture2D newTex = LoadTexture2DInStorage(directoryMd5Path);//讀取 logo.texture = newTex;//顯示 Debug.Log("<color = #FFD505> +++++++ " + newTex.name + "+++++++++++++++++ </color> "); SaveTempDicTextture(texNameMd5, newTex);//存入字典(臨時儲存) tryCount = 10; break;//結束 } } if (!andios || (andios && !File.Exists(directoryMd5Path))) {//從伺服器下載圖片後存入記憶體 if (url.Length <= 10) {//長度不夠則為無效url,載入預設頭像 logo.texture = LoadDefaultTexture(texNameMd5); tryCount = 10; break;//結束 } else {//長度夠則為有效url,下載頭像 WWW www = new WWW(url); yield return www; Debug.Log("頭像下載完畢"); if (string.IsNullOrEmpty(www.error)) { //www快取時有缺陷,2種方式存記憶體 Texture2D wwwTex = new Texture2D(www.texture.width, www.texture.height, TextureFormat.RGB24, false); www.LoadImageIntoTexture(wwwTex); //Texture2D wwwTex = www.texture; logo.texture = wwwTex;//顯示 SaveTempDicTextture(texNameMd5, wwwTex);//存入字典(臨時儲存) if (andios && !File.Exists(directoryMd5Path)) WebTestDownload(url, directoryMd5Path);//存入手機記憶體 while (!File.Exists(directoryMd5Path)) { yield return 0; } Texture2D newTex = LoadTexture2DInStorage(directoryMd5Path);//讀取內建 SaveTempDicTextture(texNameMd5, newTex);//存入字典(臨時儲存) tryCount = 10; break;//結束 } else tryCount++;//重新下載嘗試+1 } } } } } /// <summary> /// web下載 /// </summary> /// <param name="url"></param> /// <param name="isAddRandomParams"></param> /// <param name="callback"></param> /// <param name="progress"></param> public void DownloadBytes(string url, bool isAddRandomParams = true, Action<bool, byte[]> callback = null, Action<float> progress = null) { if (downloadWWW == null) Init(); downloadWWW.DownloadBytes(url, isAddRandomParams, callback, progress, 3); } /// <summary> /// 使用協程下載檔案 /// </summary> public void WebTestDownload(string url, string filepath) { //string url = "http://192.168.70.88:8000/Android/weekly/last/1001.prefab.k_d4a807497e976cbadd197c90160ef3ee"; DownloadBytes(url, true, (ok, bytes) => { if (ok) { //string filepath = Application.persistentDataPath + "/1001.prefab.k"; File.WriteAllBytes(filepath, bytes); Debug.Log("Download Success: " + filepath + ", " + File.Exists(filepath)); } }); } /// <summary> /// 連線htttp請求 解析返回內容 /// </summary> /// <param name="url"></param> /// <returns></returns> public string HttpGet(string url) { string str=null; HttpWebRequest res = (HttpWebRequest)WebRequest.Create(url); res.Method = "GET"; res.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)res.GetResponse(); Stream strRes = response.GetResponseStream(); StreamReader read = new StreamReader(strRes,Encoding.GetEncoding("utf-8")); str = read.ReadToEnd(); Debug.Log(str); strRes.Close(); read.Close(); return str; } }
怎麼使用呢?只需要在場景中一個物體上掛載HttpManager.cs,
HttpManager httpManager = go.GetComponent《HttpManager》();//去它身上拿到HttpManager指令碼
httpManager.LoadImage(imageURL, obj);//傳入下載地址和需要改變圖片的物體