quick中使用指定格式加载精灵图片

在cocos2dx中,图片默认是使用RGBA8888来加载图片的,这样的结果就是在默认情况下,虽然你用了jpg或者压缩过的png,你的包是小了,但是你发现使用的内存并没有减少?why?
譬如,我使用一张jpg图片做背景图,图片大小为640*1366-109KB,使用这张图片加载初始化一个精灵,它占用的内存竟然是640 x 1136 @ 32 bpp => 2840kb。其实quick提供了使用某种格式加载图片的接口,但是群里之前就有朋友说不管用,我当时也没有搞这块,所以也没有细看,今天测试了一下,才发现确实有问题,是一个很容易解决,但发现解决方法后,你保准跟我一样,会大吼一句,这TM坑爹呢?其实我也觉得有点略坑爹。其实算是一个小bug!好了,我们就来慢慢扒吧!
1.我们先来看下display.newSprite中的这段代码

if display.TEXTURES_PIXEL_FORMAT then
     cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT)
     sprite = spriteClass:create(filename)
     cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2D_PIXEL_FORMAT_RGBA8888)
else
     if params and params.capInsets then
           sprite = spriteClass:create(params.capInsets, filename)
     else
           sprite = spriteClass:create(filename)
     end
 end


```

这段代码中,我们可以看到,quick在你通过文件名来初始化精灵的时候,它会去在一个叫display.TEXTURES_PIXEL_FORMAT的table里寻找你是否为这个文件设置了加载格式,如果设置了,它就调用cc.Texture2D:setDefaultAlphaPixelFormat(display.TEXTURES_PIXEL_FORMAT)来使用你设置的方式加载精灵,然后再将默认的加载格式重置为原来的cc.TEXTURE2D_PIXEL_FORMAT_RGBA8888。那么问题来了,display.TEXTURES_PIXEL_FORMAT中保存的文件与对应的加载格式是怎么添加进去的?
2.找到display中下面的代码
function display.setTexturePixelFormat(filename, format)
    display.TEXTURES_PIXEL_FORMAT = format
end


```

没错,你需要调用display提供的这个接口来为你设置每张图片的加载格式,但是我在初始化精灵前先调用了这个接口设置了加载格式之后,完全没有效果,我百思不得廖大的妹啊。
于是乎开始在各个关键位置打log,终于让我发现即便调用display.setTexturePixelFormat设置了格式后,在display.newSprite做判断if display.TEXTURES_PIXEL_FORMAT then也永远都是假,甚至于display.TEXTURES_PIXEL_FORMAT永远都是一个空table。至此,我坚信一定是我使用的姿势不对,于是又从流程头撸了一遍,终于让我发现,即便执行了display.TEXTURES_PIXEL_FORMAT = format这句之后display.TEXTURES_PIXEL_FORMAT依然是个空的table,amazing!抽根烟之后灵机一动,打印了一下format,发现是nil。大家都知道,给一个table的key赋值nil,是无用的!所以,display.TEXTURES_PIXEL_FORMAT永远是空!而我的调用如下:display.setTexturePixelFormat("UI/BackGround/main_bg.jpg", cc.TEXTURE2D_PIXEL_FORMAT_RGB565),也就是说cc.TEXTURE2D_PIXEL_FORMAT_RGB565!怎么会呢,cc.TEXTURE2D_PIXEL_FORMAT_RGB565明明就在framework/cocos2d/Cocos2dConstants.lua中定义的啊,怎么会是nil呢?那只能是每加载了,但是display.newSprite里明明就直接使用了。
搜索了一下framework,发现的确哪里都没有引用Cocos2dConstants.lua这个文件,那为啥display.newSprite就敢直接用呢?
我猛然间想起来3.3中,与framework文件夹同目录下有个cocos目录,而在cocos/cocos2d下同样有个Cocos2dConstants.lua文件,与framework中的基本一模一样,而在cocos的init.lua中加载了这个文件。那么既然加载了,为毛还不行?
问题来了,致廖大and七月:
framework的Cocos2dConstants中定义如下:
cc.TEXTURE2D_PIXEL_FORMAT_AUTO      = 0x0
cc.TEXTURE2D_PIXEL_FORMAT_BGRA8888  = 0x1
cc.TEXTURE2D_PIXEL_FORMAT_RGBA8888  = 0x2
cc.TEXTURE2D_PIXEL_FORMAT_RGB888    = 0x3

cocos的Cocos2dConstants中定义如下:
cc.TEXTURE2_D_PIXEL_FORMAT_AUTO = 0x0
cc.TEXTURE2_D_PIXEL_FORMAT_BGR_A8888 = 0x1
cc.TEXTURE2_D_PIXEL_FORMAT_RGB_A8888 = 0x2
cc.TEXTURE2_D_PIXEL_FORMAT_RG_B888    = 0x3

是的,原因就是cocos中的Cocos2dConstants的定义跟原framework中的定义是不一样的,而display中还是使用的旧的格式!
既然找到原因了如何解决呢?但是是在cocos中的Cocos2dConstants中寻找相关变量的定义来设置图片格式!
这里就要吐槽一下了:弄俩基本一样的文件也无妨,但能合并还是合并一下吧?或者重复的东西搞成一致也是好的啊!个人觉得原framework中的格式容易记,新的一会都断在A,一会断在B的,搞锤锤!
好了,怎么改就是官方的事情了,找到问题后,如下使用
首先修改替换display中所有的TEXTURE2D_PIXEL_FORMAT_RGBA8888为TEXTURE2_D_PIXEL_FORMAT_RGB_A8888
然后
 display.setTexturePixelFormat("UI/BackGround/main_bg.jpg", cc.TEXTURE2D_PIXEL_FORMAT_RG_B565)
 self.bg = display.newSprite("UI/BackGround/main_bg.jpg", display.cx, display.cy):addTo(self)
你再查看下内存占用就看到占用明显减少了,当然,你也会发现图片不如原来质量高了!

别告诉我你不知道怎么查看内存占用,请设置config中的DEBUG_MEM = true!

确实有这个问题,一直没来得及合并,谢谢三刀的反馈,后面会作修改

:904: 厉害哈!

刀哥略屌,哈哈

异步加载就不行。

可以的,重置格式的那边改下就行了

是的,稍微修改下就可以!但正常使用的人谁知道这事啊!

顶~!!!!!!!!!!!:2:

为什么我得到的结果:LUA VM MEMORY USED: 3565 没有发生变化(这个反而高了100KB)
但纹理图片是变化了。
测试前: rc=3 id=3 640 x 640 @ 32 bpp=> 1600KB
测试前: rc=3 id=3 640 @ 16 bpp=> 800KB

quick这里的这个默认值为什么是rgba8888而不是auto