02. 06. 09
业界大牛 Thibault Imbert (bytearray.org) 近日将很常用的JPEGEncoder类用vector类改写了一下,做了一个vector版本的JPG编码类,效率大幅提升。正好,前不久我也已经做了一个vector版本的JPEG编码类,在项目中使用,最近正在整理代码准备分享出来。当然啦,我所做的没有Thibault那么深入,仅仅是把Array换成Vector,所以现在就拿他的版本重新修改了一下,加上了异步功能。
所谓的异步编码,是延时处理代替循环处理。比如写入1000行文字到一个文件内,可以用for/while循环1000次,一次性写入,这就是同步处理;也可以写1行,隔0.5秒再写下一行,再隔0.5秒继续写下一行,这就是异步处理。同步处理的好处是快速,但是对计算机的压力也比较大,在浏览器中使用时,会造成假死,可能会引发稳定性问题。
Vector的效率比Array高了大约4~10倍,但还是不够高,Alchemy或者haxe的效率会更高一些,因为它们使用了Flash10未公开的opcodes接口,可以直接操作一段内存数据。Mateusz Malczak(http://segfaultlabs.com)做了一个异步Alchemy版的JPEGEncoder,效果很赞,速度比我vector异步版的要快很多,但是缺少了一些自定义参数设置(在压缩小图片的时候,看上去效率反而不如Vector,其实不然,实际上,这是因为程序中写死了大小2800×2800)。Alchemy的C源码修改起来也比较麻烦,要用Alchemy重新编译。而且因为编译了整个libjpeg,所以文件体积也比较大,用C重新写一遍所有相关的类可以解决大小问题,但问题也会更加麻烦。看起来,haxe生成的swc应当是最佳选择,正在考虑有空的时候改写一个。
我将这个几个放在一起,来看一下例子吧!(需要安装Flash Player10)
下载 源文件
下载 带有异步压缩功能的vector版JPEGEncoder
关于 Alchemy 和 Haxe:
Alchemy 是Adobe实验室的一个项目,它的前身是Scott Petersen的“FlaCC (Flash C Compiler)”,目标是让C语言写的类能够被Flash重用。在MAX 2007 大会上,Scott凭借Flash中畅玩Doom一鸣惊人。Alchemy可以将C语言代码变成Flash可用的swc文件。这种方式类似于在C语言里面直接执行汇编语言,效率自然提高很多。目前Alchemy还只是测试项目,但是已经开放了SDK下载,可以编译许多常用的C类库。
Haxe 是传奇的 Nicolas Cannasse 创造的语言。Nicolas 发明了大名鼎鼎的MTASC (Motion-Tween Actionscript Compiler),在AS2.0的时代,改变了AS开发的方式,Flash也进入开源时代。进入AS3.0时代后,Nicolas选择了自己创造一种语言,这种语言吸取了Flash的优点,并且在语言和编译器上做了很多优化,使得效率上大幅度提升,这就是Haxe。时至今日,Haxe已经发展为一个丰富、高效的高级语言,也对Actionscript的发展产生了影响,例如Flash10的Vector,就和Haxe的概念和语法非常相似。
Alchemy公开之后,Nicolas 找到了 Flash播放器中留给Alchemy的未公开的接口,通过这些接口,AS可以直接操作一段内存中的数据。Haxe也使用了这些接口,并称之为Flash Memory,借助Alchemy的接口,Haxe的效率也大为提升。
18. 04. 09
1. 中文乱码问题和解决方案
新安装的 Flashdevelop 打开有中文的文件时,会有乱码现象,如图:

手动选择编码为UTF-8格式(File -> encoding -> UTF-8 ),会发现如果汉字是奇数个一起的时候,最后几个字符会变成乱码。这是由于 Flashdevelop 读取文件,没有找到文件内的编码标记,就默认以8bit方式读取,再转回utf-8格式的时候就会出问题。
解决方案:
选择菜单 Tools – 将设置中的 Fallback Codepage 设置为utf-8,这样flashdevelop在不知道文件应该用什么编码的时候,就会以utf-8处理。这里顺便也将其他几个编码设为utf-8,这样就更好了。

2. 修改默认字体大小
默认情况下中文字比较小,看着会比较累。选择 Tools -> Syntax Color… 就可以修改了。
注意哦,默认只是改编辑AS3 的字体。我就犯了错,拿AS3的设置修改,然后看XML文件的显示效果,结果发现怎么改都没效果 -__-!
我用的是Verdanda/10pt, 最终的效果:

06. 04. 09
FileReference用来上传文件,结合FileReferenceList使用,可以弹出一次文件选择框就上传很多个文件,比HTML form形式的友好很多。但是使用的时候,有些地方需要注意的:
- 上传文件时,不能增加自定义request header
这点不同于URLLoader:URLLoader是可以增加自定义头部信息(request header)到对应的URLRequest对象中的,但是敏感的字段是不可以更改的,比如refer、cookie、host等等;而FileReferrence.upload使用的URLRequest,则不可以增加任何自定义头信息,所有自己添加的自定义header,都被播放器悄无声息地忽略掉了,没有任何报错和提示。如果一定要增加字段,只能添加到POST变量中。
- 只有在IE浏览器中, Filereference 才能附带浏览器Cookie信息
这是一个很汗的bug,在非IE浏览器中,利用FileReference发出的HTTP请求,带的cookie资料都是IE的cookie。即便在Firefox或者chrome中,传送的cookie也是IE的!有的同学说这和默认浏览器设置有关,例如将默认浏览器设为Firefox,那么IE就得不到cookie。但是我测试了一下,发现无论默认浏览器是什么,发送的都是IE的cookie。解决方案暂时是借用JS得到cookie( ExternalInterface.call(”javascript:document.cookie”) ),当作变量post过去。服务器端也要做相应的调整,比较麻烦,针对非IE浏览器用非Cookie方式验证。
- Filereference 得不到文件的本地路径
Flash10的Filereference可以得到本地文件的二进制文件 (存放在filereference.data)中,但是得不到文件路径(file://…)。这个问题还附带导致了一个问题,FilereferrenceList不能判断出重复选择的文件。就是说第一次弹出文件选择对话框的时候,用户选择了一个文件。过了一段时间再继续浏览文件,又选择了这个文件,这时候Flash是没有办法知道重复选择的。
- 不能设置上传的content-type
给Filereference.upload 使用的URLRequest,是受一些安全性限制的,除了本身的一些关键字段不能修改之外,contnent-type属性也不能修改。可能会让人郁闷的是,这个也没有任何throw/warning报错。content-type的值恒定为 “ application/octet-stream ”。
- Filereference只支持实际存在的文件的上传下载
要是要上传一些动态生成的数据到服务器存储,那就用不得Filereference,也看不到上传进度了。
内存里面的数据,希望上传到服务器保存为文件,可以用URLLoader,URLStream之类的代替。但是FlashPlayer10有个新增的安全性限制,当上传文件的时候,播放器会检查操作是否由用户点击触发。没有点击就上传,会被浏览器阻挡掉请求。播放器判断一个HTTP请求是否是文件上传的依据是form-based-HTML-file-upload规范,有两个标志:
一是content-type含有“ multipart”,例如“multipart/form-data”,“mymultipartxxx”;
二是字段名含有 filename。
满足了这两点,flash播放器就会把这次请求当作文件上传处理,进而检查是否符合安全限制。要防止被阻挡掉也很简单,不要用filename这个关键字做数据的字段名即可。