一.1张图片内存如何计算

一张图片占用的内存由以下两个因素决定:

  • 图片的像素点个数
  • 单位像素占用的字节数

其中图片的像素点个数是图片的宽度与长度的积,所以一张图片占用的内存值为:

图片长度  *  图片宽度  *  单位像素占用的字节数

单位像素所占用的字节数与图片的解码方式有关。
默认情况下,在cocos里加载一张图片,每一个像素点使用4个byte来表示1个byte(8位)代表red,另外3个byte分别代表green、blue和alpha透明通道。这个就简称RGBA8888.

举例来说,一张1136x640的背景图占用的内存为 1136x640x32/8 = 2840 KB

当然我们也可以改变图片的解码格式:

cc.Texture2D.setDefaultAlphaPixelFormat(cc.Texture2D.PIXEL_FORMAT_RGBA4444)

此时,图片的解码都会使用RGBA4444

举例来说,一张1136x640的背景图占用的内存为 1136x640x16/8 = 1420 KB

这里有个问题:首先,纹理像素格式的改变会影响后面加载的所有纹理。因此,如果你想后面加载纹理使用不同的像素格式的话,必须再调用此方法,并且重新设置一遍像素格式。

其次,如果你的CCTexture2D设置的像素格式与图片本身的像素格式不匹配的话,就会导致显示严重失真。比如颜色不对,或者透明度不对等等。


二.cocos支持的纹理像素格式

AUTO 自动检测模式
BGRA8888 32-bit纹理
RGBA8888 32-bit纹理
RGB888 24-bit纹理
RGB565 16-bit纹理,不带Alpha通道
A8 用作遮罩(masks)的8-bit纹理
I8 8-bit intensity纹理
AI88 用作遮罩的16-bit纹理
RGBA4444 16-bit纹理
RGB5A1 16-bit纹理
PVRTC4 4-bit PVRTC压缩纹理 texture
PVRTC4A 4-bit PVRTC压缩纹理: PVRTC4 (has alpha channel)
PVRTC2 2-bit PVRTC压缩纹理: PVRTC2
PVRTC2A 2-bit PVRTC压缩纹理: PVRTC2 (has alpha channel)
ETC ETC压缩纹理
S3TC_DXT1 S3TC压缩纹理
S3TC_DXT3 S3TC压缩纹理
S3TC_DXT5 S3TC压缩纹理
ATC_RGB ATITC压缩纹理
ATC_EXPLICIT_ALPHA ATITC压缩纹理
ATC_INTERPOLATED_ALPHA ATITC压缩纹理

RGBA8888是默认的格式。

对于16位的纹理来说,使用RGB565可以获得最佳颜色质量,因为16位全部用来显示颜色:总共有65536总颜色值。但是,这里有个缺点,除非图片是矩形的,并且没有透明像素。所以RBG565格式比较适合背景图片和一些矩形的用户控件。

RBG5A1格式使用一位颜色来表示alpha通道,因此图片可以拥有透明区域。只是,1位似乎有点不够用,它只能表示32768种可用颜色值。而且图片要么只能全部是透明像素,或者全部是不透明的像素。因为一位的alpha通道的缘故,所以没有中间值。但是你可以使用fade in/out动作来改变纹理的opacity属性。

如果你的图片包含有半透明的区域,那么RBGA4444格式很有用。它允许每一个像素值有127个alpha值,因此透明效率与RGBA8888格式的纹理差别不是很大。但是,由于颜色总量减少至4096,所以,RBGA4444是16位图片格式里面颜色质量最差的。

现在,你可以得到16位纹理的不足之处了:它由于颜色总量的减少,有一些图片显示起来可能会失真,而且可能会产生“梯度”。


三.如何优化内存

1.忽视文件图片大小

图片文件大小和纹理内存占用是两码事。假设他们是帐篷。图片文件就相当于帐篷被装在行李箱。但是,如果你想要使用帐篷的话,它必须被撑起来,被“膨胀”。
图片文件和纹理的关系与此类似。图片文件大多是压缩过的,它们被使用的话必须先解压缩,然后才能会GPU所处理,变成我们熟知的纹理。
一个2048*2048的png图片,采用32位颜色深度编码,那么它在磁盘上占用空间只有2MB。但是,如果变成纹理,它将消耗16MB的内存!

2.用SetDefaultAlphaPixelFormat()来实现

尽量使用颜色深度为16bit的图片。但是前面也提到了,如果图片本身的颜色深度如果是32位。但是用SetDefaultAlphaPixelFormat()设置成16位。则可能让图片失真.图片看起来就很模糊,这当然是有解决的办法,庆幸我们有TexturePacker(TP)工具.
TP有一个特性叫做“抖动”,它可以使得原本由于颜色数量减少而产生的失真问题得到改善。
特别是在拥有Retina显示的像素密度下,你几乎看不出16位与32位的纹理之间的显示差别。当然,前提是你需要采用“抖动”算法。

抖动算法

3.使用NPOT纹理

NOPT是“non power of two”的缩写,译作“不是2的幂”。如果纹理图集(texture atlas)使用NPOT的纹理,它将有一个具大的优势:它允许TP更好地压缩纹理。因此,我们会更少地浪费纹理图集的空白区域。而且,这样的纹理在加载的时候,会少使用1%到49%左右的内存。而且你可以使用TP强制生成NPOT的纹理。

4.使用pvr格式纹理

因为jpg是没有透明色的,一个像素最多3字节,而png一个像素4字节,jpg纹理应该占用内存更小才对,但是cocos把所有纹理转换成rgba8888格式,所以无论是jpg还是png,占用的都是4字节。正因cocos2d对其他纹理支持不够好,pvr才会显得那么高效。

pvr格式可以被显卡所认可,而不需要开辟临时内存来读取,所以即便同为argb8888格式的图片,pvr也会比png有效率,虽然不会节约程序稳定运行时的内存,但是会避免加载大量图片时的内存暴涨。 并且如果是ios设备的话,可以使用pvrtc4格式的图片,这个格式相当于windows下的dds图片,是可以被显卡直接支持的。它是有损压缩,一个像素只占4位,不过如果不是有渐变半透明色的话,一般效果可以接受,而其节约的内存和cpu时间非常非常显著。

pvr也不是万金油。android设备下虽然可以使用pvr格式,但是不能使用pvrtc4,希望通过pvr像ios设备上一样真正减少游戏内存是不太可行的。

pvr.ccz其实就是pvr图片zip打包下,程序读的时候还是先解压出pvr资源,然后再读取pvr。不过由于压缩下可以极大的减小图片体积,所以虽然多了解压过程也不会有特别多的cpu消耗。

一张jpg图片实际加载过程内存消耗,以一张1024*1024 argb8888 500k的jpg图片为例: a.读取图片文件(消耗图片大小内存,500k) b、解析jpg数据(cgimage, 4mb) c、释放500k的图片内存 d、opengl纹理数据(4mb) e、释放cgimage的4mb内存。 注意,这个过程不是必然的顺序执行,释放cgimage内存的实际是有系统决定的,会很快,但是不一定是立即执行。 所以内存会瞬间飙升9mb左右,然后减少5mb,稳定到4mb左右.

png图片的加载过程与此相同.

pvr图片可以节约解析图片数据到纹理这一步的消耗。也就是说读取pvr图片资源(等价于解压pvr.ccz到内存,如果是1024*1024 argb8888格式的话,那么图片大小就是4mb,ccz压缩后图片1mb左右)消耗4mb,将pvr图片数据提交给显卡消耗4mb。然后释放文件数据4mb。这么看似乎跟Png从内存占用上相比也不是非常有优势。(注意这里说的pvr是指pvr封装的argb8888,与pvrtc4的性能有天壤之别)

这里还有一点需要说明,一般我们处理windows下的dds纹理的时候,都习惯将其按2的整次幂对其,虽然图片内容只有900*900,但是图片大小却是1024*1024。那我们读取这个图片所消耗的内存就是4mb,按2的整次幂对其是有助于提高运行效率的,但是不是非常必须的。ios和android的设备都支持非2的整次幂的纹理。所以如果是png图片,那么它该多大就多大。此时消耗的内存就只有900*900*4=3mb。

rgb565和rgb5551的图片所消耗的内存是rgba8888的一半,如果没有透明渐变的话,视觉上也看不出什么区别。一些大的背景图可以优先选择这种格式。

pvr图片加载速度要比png和jpg快3~5倍(同样1024*1024 argb8888),png消耗的时间可能是700ms左右,但是pvr只需要100ms左右。如果是pvr.ccz压缩下,消耗的时间是200ms左右。可见pvr在加载速度上还是有非常大的优势的。这个应该是因为png和jpg需要把图片数据还原为rgba,但是pvr可以直接把图片数据传递给显卡。pvrtc4的图片是可以被powervr显卡直接支持的。

cocos-js,内存管理2---计算图片占用内存相关推荐

  1. 桌面内存管理器(dwn.exe)占用内存过高时怎么办?

    桌面内存管理器(dwn.exe)占用内存过高,可以解决的办法多种多样. 桌面内存管理器(dwn.exe)占用内存过高主要是因为存在DWM内存泄漏, 也正是因为这样,DWN内存泄露,不会自动回收内存,导 ...

  2. Sqlserver内存管理:限制最大占用内存(转载)

    https://blog.csdn.net/donghustone/article/details/83338185?tdsourcetag=s_pcqq_aiomsg 转载于:https://www ...

  3. android 图片占用内存的计算

    Android高效内存1:一张图片占用多少内存 在做内存优化的时候,我们发现除了解决内存泄露问题,剩下的就只有想办法减少真实的内存占用.而在App中,大部分内存可能被我们图片占用了,所以减少图片的内存 ...

  4. android 图片占用内存大小及加载解析

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 在讲解图片占用内存前,我们先问自己几个问题: 我们在对手机进行屏幕适时,常想可不可以只切一套图适配所有的手机呢? 一张图片加载到手 ...

  5. 安卓图片内存优化(一)——图片占用内存大小的计算

    安卓开发中经常会遇到因为图片处理不当导致的oom问题,因为系统分配给每个应用的最大内存空间是有限的,正常只有几十上百兆(排除通过特殊手段获取到几百兆内存空间的情况).所以为了节省更多的空间需要对图片进 ...

  6. 安卓中图片占用内存大小分析

    相关概念: 位深 色彩空间 颜色通道 int型占用字节 位深: 位是二进制的位.位深是指计算机系统中图片的一个像素点占用的二进制位数.例如位深32,就是使用2^8 = 32 位二进制来表示像素值.例如 ...

  7. Android 中图片占用内存分析

    Android 在加载图片的时候一定会考虑到的一个点就是如何防止 OOM,那么一张图片在加载的时候到底会占用多少内存呢?有哪些因素会影响占用的内存呢?知道了这些,我们才能知道可以从哪些点去优化,从而避 ...

  8. Android | 如何计算图片占用内存的大小

    前言 对于一张图片,你知道应该存放在那个资源目录下面吗,或者说,放在那个资源目录下加载起来更省内存呢?在日常开发中我们可能不太注意这些东西,但是这些却是基础,是必不可少的一环,所以这几天重新温习了一下 ...

  9. per.ccz与png图片占用内存对比

    pvr相比png优势 1.压缩,2gpu能直接识别,不需要额外的内存开销,3.可以自定义色深 pvr与png的内存占用    转载▼ Zwoptex生成的spritesheet除了可以导出png格式的 ...

最新文章

  1. Zookeeper的多节点集群详细启动步骤(3或5节点)
  2. [2017-2018上 网络工程] 面向对象预习任务
  3. 从薪资、需求来分析,武汉Java开发就业前景好不好?
  4. 基于GPU的K-Means聚类算法
  5. Ubuntu系统opencv4.4 opencv_contribute安装常见问题
  6. python 遍历一个空列表
  7. typescript 静态_关于TypeScript静态成员的全部信息| TypeScript OOP
  8. 【Python3网络爬虫开发实战】 1.2.2-Selenium的安装
  9. python基础知识学习笔记(2)
  10. Android数据存储:Shared Preferences
  11. 移动魔百和M302A-ZN-S905L2_蓝牙语音正常_线刷免费固件包
  12. linux查找文件重复项,Linux中如何使用命令查找重复文件
  13. pymysql操作MySQL数据库表-----爬虫豆瓣top250电影并存入数据库
  14. 几个VC6.0到VC9.0的错误解决方案
  15. C++实现LR(1)分析表的构造
  16. 运营干货:虾皮店铺装修怎么做?
  17. 生猪价格matlab,基于时间序列的BP神经网络猪肉价格预测
  18. PMD相位提取及相位展开简述
  19. 2016年全国管理类硕士研究生考试——英语复习心得
  20. ARM硬件接口及总线介绍

热门文章

  1. JAMA Psychiatry:社区劣势与青少年神经认知和大脑结构的关系
  2. webpack应用案例之美团app
  3. 基于SOM-TL437x核心板研发的一款TI ARM Cortex-A9开发板 6JTAG仿真器接口
  4. HTML使用字体图标( tff / woff )
  5. 2020年 全国大学生创业服务网,第六届 互联网+大赛报名流程(如何同意对方邀请)
  6. 《开局一条狗》技术支持网址
  7. 学习日记2020-11-23论文学习
  8. 机器学习-吴恩达网易云课堂笔记
  9. Android开发使用ServerSocket ServerSocketChannel DatagramSocket进行TCP UDP通信 实现服务器与APP消息推送
  10. 下载Word文档的四种方法