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原创博客,请大家多多支持,转载标明出处

原文地址:https://www.cnblogs.com/Jason-c/p/13535769.html