好久不寫博客了,一是因為結婚以后變得越來越懶,二是因為新冠疫情期間忙着換工作,程序轉產品,產品干了多半年以后,又從產品轉回了程序員,在這里也給想轉崗的童鞋一些建議,不要盲目轉崗,不要覺得產品經理不就是每天開開會,寫寫文檔嗎,的確,你想的沒錯,他們就是每天的日子就是這樣瀟灑,不過這並不意味着產品經理這個崗位適合每個人,個人感覺人人都是產品經理的口號,的確是一個大坑,既破壞了產品行業的市場,也低估了產品經理崗位的難度。如果真的打算轉崗,也要拿出一段時間,學習新的崗位所需要的基本技能,然后做好受打擊的准備,新的崗位,就意味着從新開始,之前的經驗將不再適應,從受人尊敬的技術大牛,到處處受氣的產品小白,這種落差一定要有心理准備,薪資肯定也會降。我不只一次聽到我周圍的同事說:唉,程序員再干兩年,掙夠錢就轉產品。
我要說的是,產品不是養老,回家種地才是。
年紀大了,就愛感慨,廢話少敘,步入正題。
1、關於為什么要將圖片轉成DXT格式,我這里做了一些統計:
3、新建空工程下驗證加載一張5376*2688的jpg圖片,圖片為43352064字節,所以理論上應占內存41.3MB,壓縮后圖片7225344字節,理論上應占內存6.89MB a)直接加載耗時 179.26 毫秒,Profiler顯示Textures增加了96.4Mb內存 b)直接加載並壓縮耗時 394.46毫秒,Profiler顯示Textures增加了13.8Mb內存。 c)加載保存在本地的壓縮后的byte[]耗時 36.50到52.91 毫秒之間。Profiler顯示Textures增加了13.8Mb內存
由此我們可以得出結論,將圖片壓縮后的byte[]保存在本地,然后直接讀取該byte[]速度最快,從Profiler上看的內存是理論占用內存的二倍(在新建的空工程下)。
這或許將會對我們的程序優化有很大幫助,我們要做的就是,在下載完圖片,將圖片壓縮成DXT格式,我們就能得到更加流暢的程序體驗。
2、那么我們需要怎么做呢
其實很簡單,按照Unity官方文檔的說法,Texture2D.Compress就可以搞定
可是好不好用,試了才知道,這就引出了上文提到的統計。
加載完圖片,再調用Compress方法進行壓縮,非常耗時,最終的結果是程序卡頓,當然也會有杠精說用協程異步加載不就好了嗎,你說的都對,咱不跟你抬杠。
有心的童鞋就會想到,我們為什么不將調用Compress方法進行壓縮后的數據保存起來,以后每次只加載圖片壓縮后的數據呢,從上文提到的統計中可以看出,
這種思路的確不失為一種比較好的方式。
3、具體實現
前戲鋪墊的有點長,終於到重點,打字也累了直接上代碼,真的是越來越懶了
/// <summary> /// 圖片壓縮成DXT格式 /// </summary> /// <param name="path"></param> public static void CompressDXT(string path) { //讀圖片 FileStream readStream = new FileStream(path, FileMode.Open, FileAccess.Read); readStream.Seek(0, SeekOrigin.Begin); byte[] bytes = new byte[readStream.Length]; readStream.Read(bytes, 0, (int)readStream.Length); readStream.Close(); readStream.Dispose(); Texture2D texture2D = new Texture2D(600, 300, TextureFormat.ARGB32, false); texture2D.LoadImage(bytes); texture2D.Compress(true);//壓縮 byte[] imgWidth = BitConverter.GetBytes(texture2D.width); byte[] imgHeight = BitConverter.GetBytes(texture2D.height); byte[] imgformat = BitConverter.GetBytes((int)texture2D.format); byte[] imgData = texture2D.GetRawTextureData(); //將壓縮后的圖片寫入本地 FileStream writeStream = new FileStream(path + "_dxt", FileMode.OpenOrCreate, FileAccess.ReadWrite); writeStream.Seek(0, SeekOrigin.Begin); writeStream.Write(imgWidth, 0, 4);//一個int占4個字節 writeStream.Seek(4, SeekOrigin.Begin); writeStream.Write(imgHeight, 0, 4); writeStream.Seek(8, SeekOrigin.Begin); writeStream.Write(imgformat, 0, 4); writeStream.Seek(12, SeekOrigin.Begin); writeStream.Write(imgData, 0, imgData.Length); writeStream.Close(); writeStream.Dispose(); if (File.Exists(path)) File.Delete(path); }
/// <summary> /// 加載DXT格式 /// </summary> /// <param name="loadpath"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="type"></param> /// <param name="autoCubeSize"></param> /// <returns></returns> public static Texture2D LoadDXT(string loadpath) { if (!File.Exists(loadpath)) return null; FileStream fileStream = new FileStream(loadpath, FileMode.Open, FileAccess.Read); byte[] imgWidth = new byte[4]; byte[] imgHeight = new byte[4]; byte[] imgformat = new byte[4]; byte[] imgData = new byte[(int)fileStream.Length - 12]; fileStream.Seek(0, SeekOrigin.Begin); fileStream.Read(imgWidth, 0, 4); fileStream.Seek(4, SeekOrigin.Begin); fileStream.Read(imgHeight, 0, 4); fileStream.Seek(8, SeekOrigin.Begin); fileStream.Read(imgformat, 0, 4); fileStream.Seek(12, SeekOrigin.Begin); fileStream.Read(imgData, 0, (int)fileStream.Length - 12); fileStream.Close(); fileStream.Dispose(); //創建Texture Texture2D texture2D = new Texture2D(BitConverter.ToInt32(imgWidth, 0), BitConverter.ToInt32(imgHeight, 0), (TextureFormat)BitConverter.ToInt32(imgformat, 0), false); texture2D.LoadRawTextureData(imgData); texture2D.Apply(); Resources.UnloadUnusedAssets(); return texture2D; }
Jason_c原創博客,請大家多多支持,轉載標明出處