zoukankan      html  css  js  c++  java
  • 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原创博客,请大家多多支持,转载标明出处

  • 相关阅读:
    如何正确使用Windows的Ping命令
    Web设计里的软件工程思想
    台风麦莎在8月6日凌晨登陆浙江台州
    多图展示:微软IE1.0至7.0界面回顾
    Windows XP减肥行动
    微软正版验证启动24小时内被攻破
    如果你想成功,35岁前必须做好的十件事情
    Informix数据备份小技巧
    crontab命令使用浅析
    Windows Vista公布硬件要求
  • 原文地址:https://www.cnblogs.com/Jason-c/p/13535769.html
Copyright © 2011-2022 走看看