论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Flash AS教程
Tag:2.0,3.0菜鸟,游戏,,cs,技巧,源码,,文本,文字,函数,音乐,随机,拖拽,asp,access,xml,mc,视频教程

Flash as2 中的拍照图片可以压缩的几种方法

文章类别:Flash AS | 发表日期:2009-8-2 14:54:57

  Flash as2 中的拍照图片可以压缩的几种方法

看过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,则在二维数组中进行比较,把某些点近似为该点,这样就有更多的个数了,字符数量就更加少。
具有压缩和高阶压缩选择方式的开关

高阶压缩是有效的,拿最小的数字来说,表示两个需要四个字符 0,0,
压缩后是 0(2), 多一个字符,三个数字以上就小了,如果是需要两个字符表示的,那就肯定压缩了
复制内容到剪贴板
代码:
//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);
//是否压缩
//我的测试数据:
//more:1636 ms
//true:1382 ms
//false:364 ms
var is_compress:Boolean = true;
var is_more_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;
    }
    return_code = code_array[i]+return_code;
    return return_code;
}
//
//记录的数组
var p_array:Array = new Array();
var final_array:Array = new Array();
var timer:Number = getTimer();
function save2array():Void {
    for (var i:Number = 0; i<max_w; i++) {
        for (var j:Number = 0; j<max_h; j++) {
            p_array.push(myBitmap.getPixel(i+1, j+1));
        }
    }
    var tmp_num:Number = p_array[0];
    var tmp_counter:Number = 0;
    if (is_compress) {
        //选择普通压缩
        var p_length:Number = p_array.length;
        for (var i:Number = 0; i<p_length; i++) {
            if (is_more_compress) {
                //选择再次压缩
                if (p_array[i] == tmp_num && i != p_length-1) {
                    //计数,如果是最后一个数字,需要在下面做一次整合
                    tmp_counter++;
                    continue;
                } else {
                    //判断重复个数
                    var tmp_str:String = "";
                    if (tmp_counter>0) {
                        tmp_str = "("+tmp_counter+")";
                    }
                    final_array.push(getcode(tmp_num)+tmp_str);
                    //相关数据复原
                    tmp_counter = 0;
                    tmp_num = p_array[i];
                }
            } else {
                //不选择再次压缩
                final_array[i] = getcode(p_array[i]);
            }
        }
    }
}
save2array();
//图片参数,解压的时候需要
var my_data:String = max_w+","+max_h+","+int(is_compress)+","+int(is_more_compress)+"=";
//trace(my_data);
my_data += final_array.join(",");
trace("转换时间: "+(getTimer()-timer)+" ms");
//分隔符要用那些没有做在进制字符的
trace("字符长度:"+my_data.length);
//trace(final_array);
//字符长度
//我的测试数据:
//false:302419
//true:147174
//more:130120
//trace(my_data);

视频教程列表
文章教程搜索
 
Flash AS推荐教程
Flash AS热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058