| 看过FlashK写的《关于Flash AS2 中的拍照图片传输量太大的解决思路》,也想加一个算法。 我们都说无损压缩吧,保留点阵数据。此法压缩的数据已经接近BMP格式的图片大小,我的机器花费大约1秒处理200*200的图片,比未压缩的字符的压缩比率为50%。具体图片比较黑暗则压缩更好。
 引用:未压缩文本:295k
 压缩文本:143k
 高阶压缩:127k
 BMP图片(200*200一样的图片):117k
 压缩结果类似: 引用:200,200='c,'c,'c,'c,'c,Eg,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'
 c,'c,Eg,Eg,Eg,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,R9,R9,
 R9,R9,0i,0i,0i,0i,0i,0i,0i,0i,0i,0i,0i,0i,Eg,Q9,){,)c,0i,Eg,Eg,0i,0i,0i,R9,R9,R9,R9,)c,/E,'c,0i,R9,0i,R9,R9,R9,R9,R9,R9,0i,)c,)c,R9,R9,R9,R9,R9,R9,R9,R9,R9,R9,EE
 我这里的思维是用自定义的进制来处理数字压缩的问题。 原理:按字符来算,一个数字用2进制是最长的,用十进制则更短,用16进制更短,那用尽量大的进制则字符越少。 进阶压缩算法:选择起始点算法,分段压缩,邻近同样字符用范围数表示。 先说一下本次的算法: 
 
 //program by hqlulu//www.aslibra.com
 import flash.display.BitmapData;//自定义宽和高
 var max_w:Number = 200;
 var max_h:Number = 200;
 var myBitmap:BitmapData = new BitmapData(max_w, max_h, true, 0x000000);
 myBitmap.draw(_root);
 view_mc.attachBitmap(myBitmap, 10);
 //是否压缩
 //我的测试数据:
 //true:1382 ms
 //false:364 ms
 var is_compress:Boolean = true;
 //
 //定义进制字符,在这里差不多把所有的字符用上了,用的越多压缩越好,不过选择ffffff所达到的字符数最好
 //这里对于图片加密也有很大的帮助!
 var code:String = "0123456789qwertyuiop[]asdfghjkl;zxcvbnm./QWERTYUIOP{}|ASDFGHJKL:ZXCVBNM<>?~!@#$%^&*()_+'";
 var code_array:Array = code.split("");
 //多少个字符就是多少进制了
 var byte:Number = code.length;
 function getcode(i:Number):String {
 //取整求余法
 var return_code:String = "";
 while ((i=Math.ceil(i/byte))>byte) {
 return_code += code_array[i%byte];
 }
 return_code += code_array[i];
 return return_code;
 }
 //
 //记录的数组
 var p_array:Array = new Array();
 var timer:Number = getTimer();
 function save2array():Void {
 for (var i:Number = 0; i<max_w; i++) {
 p_array[i] = new Array();
 for (var j:Number = 0; j<max_h; j++) {
 //这里不加判断的话,速度可以提高些
 if (is_compress) {
 p_array[i].push(getcode(myBitmap.getPixel(i+1, j+1)));
 } else {
 p_array[i].push(myBitmap.getPixel(i+1, j+1));
 }
 }
 }
 }
 save2array();
 trace("转换时间: "+(getTimer()-timer)+" ms");
 //分隔符要用那些没有做在进制字符的
 var my_data:String = max_w+","+max_h+"=";
 //trace(my_data);
 my_data += p_array.join(",");
 trace("字符长度:"+my_data.length);
 //字符长度
 //我的测试数据:
 //false:302419
 //true:147174
 //trace(my_data);
 执行时间不多,对于程序的有效行比较好。大家可以看一下代码的执行效果
 进阶压缩的原理: 引用:'c,'c,'c,'c,'c,Eg,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,Eg,
 Eg,Eg,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,'c,
 看到上面的数据了,对于重复的点,可以考虑这样处理: 引用:'c(5),Eg,'c(10),Eg,Eg,Eg,'c(15),
 这个算法需要再对数组处理,本人未写出,提高的压缩比率是客观的。当然"()"需要在后期先处理,把"()"的多个字符先行恢复。
 引用:0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 对于上面字符,可以看出来,如果相片偏暗,以黑色为基点运算就好,相片偏亮,则适宜以白色为基点运算。 分段压缩的算法效率不大,毕竟现在已经是三个字符表示了,如果分区间,可以用两个字符表示颜色,但是还要用一个字符表示区间。 图片压缩方法 相邻的点的颜色一样,采用"(个数)"表示如果颜色相差不大,差值为n,则在二维数组中进行比较,把某些点近似为该点,这样就有更多的个数了,字符数量就更加少。
 经典论坛讨论:http://bbs.blueidea.com/thread-2700451-1-1.html
 出处:蓝色理想
责任编辑:blue
 ◎进入论坛Flash专栏版块参加讨论
	      |