PNG压缩方案讨论

大家都知道,刀塔传奇中使用了大量的jpg图片加mask遮罩来达到图片透明的效果。

这样做最大的好处就是包小,因为jpg格式比png格式小太多,尤其是大图,即便加上mask文件也小很多,因为mask文件的特殊性,其大小真的小的可怜!
首先,我们需要一张jpg图片和一个mask文件,mask文件如何制作呢?请参考下面的文章,看了文章之后,你也就知道为啥我说mask文件的真的很小了!
http://www.cnblogs.com/U-tansuo/p/JPG-Mask.html?ADUIN=25584762&ADSESSION=1422190686&ADTAG=CLIENT.QQ.5389_.0&ADPUBNO=26441
现在,我们就有两个文件了,我的两个文件是这个样子滴:
发现传上来的图很容就挂了啊,大家自行去一楼下载附件,所用资源都再里面




有了这两文件之后,我们 还需要一个shader文件,内容如下:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
uniform sampler2D u_mask_texture;

void main() {
vec4 mask_FragColor = texture2D(u_mask_texture, v_texCoord);
    gl_FragColor = v_fragmentColor*texture2D(CC_Texture0, v_texCoord);
    gl_FragColor.a = mask_FragColor.r;
}
三个后面会传个附件。
有了这三个文件后在你的MainScene中添加如下代码:


?
1
2
3
4
5
6
7
8
9
10
11
12
self.shipBody = display.newSprite( "b1302.jpg" ):addTo(self)
self.shipBody:setPosition(display.cx, display.cy)
local fileUtiles = cc.FileUtils:getInstance()
local defaultVert = fileUtiles:getStringFromFile( "default.vsh" )
local maskFrag = fileUtiles:getStringFromFile( "mask.fsh" )
local glprogram  = cc.GLProgram:createWithByteArrays(defaultVert, maskFrag)
local glprogramstate = cc.GLProgramState:getOrCreateWithGLProgram(glprogram)
cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_I8)
local texture = cc.Director:getInstance():getTextureCache():addImage( "b1302_mask.png" )
cc.Texture2D:setDefaultAlphaPixelFormat(cc.TEXTURE2_D_PIXEL_FORMAT_RGB_A8888)
glprogramstate:setUniformTexture( "u_mask_texture" , texture)
self.shipBody:setGLProgramState(glprogramstate)
代码很简单,就是加载shader然后设置mask文件,再赋给精灵

需要注意的是加载mask的时候设置下加载的格式,因为mask只是一个位图,所以用I8格式加载就好。关于如何使用指定格式加载图片,参考我前面的帖子
http://www.cocoachina.com/bbs/read.php?tid-283098.html
总的来说代码很简单,没啥特别的地方。
另外推荐一篇文章,可以阅读以下,其中提到了如何在C++中直接做处理。

http://www.hippyless.com/blog/?p=245

从技术上来讲,是好文章,开阔了思路。 之前页游大多数有这样做的,目的是web传输下载更快捷。 


但从实用角度来讲, 

这个代价太大,只是为了减小发布包大小。 

1.要制作png & mask 
2.jpg 导致的内存上涨 
3.shader合成的代价 
4.代码复杂度 
等等 


如果大家想把发布包弄的很小,建议优化png. 使用pngquant来压缩PNG 一般压缩可以达到 70% 左右。 

http://blog.csdn.net/piao_polar/article/details/44856821

http://app.hustonline.net/article/detail/51/2#usr-cmt-list
再配合热更新方案,发布包可以做的很小。 


关于iOS缩小打包项目ipa的一些比较不错的方法,总结如下:

1、配置编译选项 (Levels选项内)Genetate Debug Symbols  设置为NO,这个配置选项应该会让你减去小半的体积。

2、舍弃架构armv7,因为armv7用于支持4s和3gs,4s是2011年11月正式上线,虽然还有小部分人在使用,但是追求包体大小的完全可以舍弃了。

3、编译的版本必须是发布版本,

4、查找内部使用到的第三方库,一方面可以进行删减代码,用不到的类,直接删除,还有第三方库中的图片资源统统删除掉,如果能够自己手写实现的,那费功夫自己写吧

单单上面的几个操作全部完成的话,项目一般能惊人小了很多。

其他的资源相关:

图片

压缩图片 不重要的图片可适当采用 8bit PNG图片

1.什么是矢量图 矢量图是由计算机的算法产生的,可以无限放大或缩小,不会有任何损失,通常由矢量软件制作。

2.什么是位图 位图是由一个一个的小色块组成,放大后会看到那些小色块,同一面积内小色块越多,分辨率就越高。

3.矢量图的优缺点 可以无限放大或缩小,不会影响图像素质,文件体积较小,编辑灵活。缺点是表达的色彩层次不清,整体观感效果不如位图

4.位图的优缺点 不能放太大,减少文件分辨率后会影响图片质量,图片战胜空间较大,优点是能很细腻地表达图片的效果,图片表达效果非常好

5.什么情况下用位图,什么情况下用矢量图 一些对图片要求高的用位图,例如照片。其他的尽量用矢量图。例如文字、表格、卡通图片等

去掉无用的图片

用代码绘制简单的纯色图片 用Sketch和PaintCode快速得到绘制代码

如果不需要使用透明,可以用jpeg代替PNG。jpeg减少了些效率但更加小。需权衡性能,大小。

对32位的图片,尽肯能的使用高压缩率,使用PS的“Save For Web”功能,可以有效的减小JPEG和PNG图片的尺寸。 默认情况下,在build时,PNG图像就被pngcrush压缩。

音频

压缩音频,尽可能使用AAC或者MP3格式,并且使用一个较低的码率。通常44.1khz的码率有点浪费,降低一定的码率也不会丢失多少音质

视频

视频也可以使用类似于音频的处理方法,音视频的压缩可以很大程度的压缩,但是要注意压缩的格式,是不是会增加编解码的负担,这要权衡考虑。

Assets

检查bundle中的无用文件,不要打包到app或者静态库中。可以点击文件,在右侧的file inspector里面的target membership中取消勾选;或者在build phase里面的Copy Bundle Resources中去掉。

确定 dead code(代码被定义但从未被调用)被剥离,build setting 里 DEAD_CODE_STRIPPING = YES。 去掉冗余的代码,即使一点冗余代码,编译后体积也是很可观的。



文/niceSYT(简书作者)
原文链接:http://www.jianshu.com/p/fe857394a61f
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值