Unity 將圖片轉為DXT格式,並保存和讀取


好久不寫博客了,一是因為結婚以后變得越來越懶,二是因為新冠疫情期間忙着換工作,程序轉產品,產品干了多半年以后,又從產品轉回了程序員,在這里也給想轉崗的童鞋一些建議,不要盲目轉崗,不要覺得產品經理不就是每天開開會,寫寫文檔嗎,的確,你想的沒錯,他們就是每天的日子就是這樣瀟灑,不過這並不意味着產品經理這個崗位適合每個人,個人感覺人人都是產品經理的口號,的確是一個大坑,既破壞了產品行業的市場,也低估了產品經理崗位的難度。如果真的打算轉崗,也要拿出一段時間,學習新的崗位所需要的基本技能,然后做好受打擊的准備,新的崗位,就意味着從新開始,之前的經驗將不再適應,從受人尊敬的技術大牛,到處處受氣的產品小白,這種落差一定要有心理准備,薪資肯定也會降。我不只一次聽到我周圍的同事說:唉,程序員再干兩年,掙夠錢就轉產品。

我要說的是,產品不是養老,回家種地才是。

年紀大了,就愛感慨,廢話少敘,步入正題。

 

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原創博客,請大家多多支持,轉載標明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM