另类Flash程序中PNG图片素材瘦身方法
在Flash游戏开发过程中,我们会用到大量的png图片资源。它的好处大家都知道,具有alpha通道,可以背景透明,因此它也成为flash游戏图片格式的首选。但是它的缺点就是较大的复杂图形的png的尺寸往往比较大,现在提供一个方法来瘦身大尺寸的png图片。
为了方便演示,先看下面一张png图片,这张图片的大小为60k。

然后大家看下面一张jpg图片,它的背景是黑色,上半部分就是我们上面的png图片,而下半部分则是把这个png图片的填充为纯白色的效果,而这张jpg图片因为没有透明图层,因此大小要比上面的png图片小很多,只有30k。(要制作这样的图片很简单:把png导入ps中,修改高度为2倍,增加一个纯黑色的背景层,再选中png图层选区,填充一个纯白色的图层并移动到图片的底部就ok了。)

那么我们怎么把这张jpg图片实现png图片的透明效果呢?这里我们就要用到BitmapData类了。假设我们已经将上面的jpg图片加载到我们的flash中来的BitmapData为jpgBmpData,那么下面的代码就可以实现png透明效果:
var bmp:BitmapData = new BitmapData(jpgBmpData.width, jpgBmpData.height / 2);
//复制图片的真实像素区域
bmp.copyPixels(jpgBmpData, new Rectangle(0, 0, bmp.width, bmp.height), new Point());
//复制图片的下半区域的红色通道到新图的alpha通道里来实现透明
bmp.copyChannel(jpgBmpData, new Rectangle(0, bmp.height, bmp.width, bmp.height), new Point(), BitmapDataChannel.RED, BitmapDataChannel.ALPHA);
//清除原始图片内存
jpgBmpData.dispose();
jpgBmpData = null;
//得到透明图片后就可以任意处理了
var logo:Bitmap = new Bitmap(bmp);
addChild(logo);
至此大功告成了,flash中的效果截图如下:

最后要注意的是,并不是所有png图片都适合这种方式,要在速度和性能之间取得平衡才是最佳方案。
补充说明:一些朋友反映文中的演示png图片如果压缩成png8或者在flash中导出再使用就已经能得到20k左右压缩结果。是的,确实如此。当初看了一些植物大战僵尸的素材就随便选了这张简单的图来做演示,并没有考虑那么多。而事实上,明白的人应该知道,此文旨在演示一种方法,而且这种方法在传统游戏中也有使用。如果认为这种方法对你没有实用价值,那非常抱歉。
六月 27th, 2010 at 17:20
保存为png8则更小,16K左右,虽然图片质量会降低一些。
六月 28th, 2010 at 00:20
我明白你的意思,我也试过。在这里用这张图片做例子不是太好。不过,这里只是演示这种方法而已。但是对于其他有阴影或者发光等效果的png图片来说,用png8也可能达不到相同的效果。而且我这个方法的最基本的前提是:已知生成的png(24位或8位)图尺寸过大,才作此变通方法。
六月 28th, 2010 at 10:13
这只是抠图吧,如果png里要半透明怎么办?
六月 28th, 2010 at 12:34
恩,可以说是抠图,半透明可以在之后再对Bitmap对象设置alpha属性。
七月 21st, 2010 at 12:07
一群蠢蛋,你这个图直接把图导入flash里,导出的SWF文件只有2K,真2
七月 21st, 2010 at 15:28
不知道谁是蠢蛋,是20k吧。我已经说过了,这个图只是随便找来做演示而已,你不削这种方法可以理解。你以为就你知道flash导出吗?要是这个图本身就是采用png8压缩过的,就算在flash中导出也没什么压缩效果。我再重复一下使用前提:已知生成png(压缩过的)图尺寸过大。
十一月 15th, 2010 at 11:12
挺好的办法,拷贝通道。
不可理喻的人,可不予理睬。这社会最不缺的就是自大不知所谓的人。
把自己的经验拿出来分享,本身是值得敬佩的。
方法没说让你用,但是不尊重别人,算什么东西?
最后,多谢作者分享!
十二月 14th, 2010 at 16:58
很好的方法……顶一个,我的方法是用的透明部分生成bytes,不透明的部分用jpg压缩,透明的用zlib压缩,到FLASH里还原,其实应该和flash本身的方法一样,但是这样做可以批量操作,FLASH跑JSFL跑不了多少文件就死了
十二月 23rd, 2010 at 12:55
我觉得最好的方式
是参考那些拍3D电影的方式
找纯色和图案不冲突的背景
然后threshold去掉不需要的部分
如果有半透明部分需要特殊图片处理后 使用draw 的混合模式
二月 10th, 2011 at 19:41
很不错的方法,可以弄个程序自动生成这样的图