PHP之生成GIF动画的实现方法


Posted in PHP onJune 07, 2013

代码如下所示:

<?
class GifMerge { 
    var $ver            = '1.1'; 
    var $dly            = 50; 
    var $mod            = 'C_FILE'; 
    var $first            = true; 
    var $use_loop            = false; 
    var $transparent        = false; 
    var $use_global_in        = false; 
    var $x                = 0; 
    var $y                = 0; 
    var $ch                = 0; 
    var $fin            = 0; 
    var $fout            = ''; 
    var $loop            = 0; 
    var $delay            = 0; 
    var $width            = 0; 
    var $height            = 0; 
    var $trans1             = 255; 
    var $trans2             = 255; 
    var $trans3             = 255; 
    var $disposal            = 2; 
    var $out_color_table_size    = 0; 
    var $local_color_table_flag    = 0; 
    var $global_color_table_size    = 0; 
    var $out_color_table_sizecode    = 0; 
    var $global_color_table_sizecode= 0; 
    var $gif            = array(0x47, 0x49, 0x46); 
    var $buffer            = array(); 
    var $local_in            = array(); 
    var $global_in            = array(); 
    var $global_out            = array(); 
    var $logical_screen_descriptor    = array(); 
    function GifMerge($images, $t1, $t2, $t3, $loop, $dl, $xpos, $ypos, $model) { 
        if($model) { 
            $this->mod = $model; 
        } 
        if($loop > -1) { 
            $this->loop = floor($loop - 1); 
            $this->use_loop = true; 
        } 
        if($t1 > -1 && $t2 > -1 && $t3 > -1) { 
            $this->trans1 = $t1; 
            $this->trans2 = $t2; 
            $this->trans3 = $t3; 
            $this->transparent = true; 
        } 
        for($i = 0; $i < count($images); $i++) { 
            $dl[$i]    ? $this->delay = $dl[$i] : $this->delay = $this->dly; 
            $xpos[$i] ? $this->x = $xpos[$i] : $this->x = 0; 
            $ypos[$i] ? $this->y = $ypos[$i] : $this->y = 0; 
            $this->start_gifmerge_process($images[$i]); 
        } 
        $this->fout .= "/x3b"; 
    } 
    function start_gifmerge_process($fp) { 
        if($this->mod == 'C_FILE') { 
            if(!$this->fin = fopen($fp, 'rb')) { 
                return; 
            } 
        } elseif($this->mod == 'C_MEMORY') { 
            $this->ch = 0; 
            $this->fin = $fp; 
        } 
        $this->getbytes(6); 
        if(!$this->arrcmp($this->buffer, $this->gif, 3)) { 
            return; 
        } 
        $this->getbytes(7); 
        if($this->first) $this->logical_screen_descriptor = $this->buffer; 
        $this->global_color_table_sizecode = $this->buffer[4] & 0x07; 
        $this->global_color_table_size = 2 << $this->global_color_table_sizecode; 
        if($this->buffer[4] & 0x80) { 
            $this->getbytes((3 * $this->global_color_table_size)); 
            for($i = 0; $i < ((3 * $this->global_color_table_size)); $i++) { 
                $this->global_in[$i] = $this->buffer[$i]; 
            } 
            if($this->out_color_table_size == 0) { 
                $this->out_color_table_size = $this->global_color_table_size; 
                $out_color_table_sizecode = $this->global_color_table_sizecode; 
                $this->global_out = $this->global_in; 
            } 
            if($this->global_color_table_size != $this->out_color_table_size || $this->arrcmp($this->global_out, $this->global_in, (3 * $this->global_color_table_size))) { 
                $this->use_global_in = true; 
            } 
        } 
        for($loop = true; $loop;) { 
            $this->getbytes(1); 
            switch($this->buffer[0]) { 
                case 0x21: 
                    $this->read_extension(); 
                    break; 
                case 0x2c: 
                    $this->read_image_descriptor(); 
                    break; 
                case 0x3b: 
                    $loop = false; 
                break; 
                default: 
                    $loop = false; 
            } 
        } 
        if($this->mod == 'C_FILE') { 
            fclose($this->fin); 
        } 
    } 
    function read_image_descriptor() { 
        $this->getbytes(9); 
        $head = $this->buffer; 
            $this->local_color_table_flag = ($this->buffer[8] & 0x80) ? true : false; 
            if($this->local_color_table_flag) { 
            $sizecode = $this->buffer[8] & 0x07; 
            $size = 2 << $sizecode; 
            $this->getbytes(3 * $size); 
            for($i = 0; $i < (3 * $size); $i++) { 
                    $this->local_in[$i] = $this->buffer[$i]; 
                } 
                if($this->out_color_table_size == 0) { 
                    $this->out_color_table_size = $size; 
                    $out_color_table_sizecode = $sizecode; 
                for($i = 0; $i < (3 * $size); $i++) 
                { 
                    $this->global_out[$i] = $this->local_in[$i]; 
                } 
                } 
            } 
            if($this->first) { 
            $this->first = false; 
            $this->fout .= "/x47/x49/x46/x38/x39/x61"; 
            if($this->width && $this->height) { 
                $this->logical_screen_descriptor[0] = $this->width & 0xFF; 
                $this->logical_screen_descriptor[1] = ($this->width & 0xFF00) >> 8; 
                $this->logical_screen_descriptor[2] = $this->height & 0xFF; 
                $this->logical_screen_descriptor[3] = ($this->height & 0xFF00) >> 8; 
            } 
            $this->logical_screen_descriptor[4] |= 0x80; 
            $this->logical_screen_descriptor[5] &= 0xF0; 
            $this->logical_screen_descriptor[6] |= $this->out_color_table_sizecode; 
            $this->putbytes($this->logical_screen_descriptor, 7); 
                $this->putbytes($this->global_out, ($this->out_color_table_size * 3)); 
            if($this->use_loop) { 
                $ns[0] = 0x21; 
                $ns[1] = 0xFF; 
                $ns[2] = 0x0B; 
                $ns[3] = 0x4e; 
                $ns[4] = 0x45; 
                $ns[5] = 0x54; 
                $ns[6] = 0x53; 
                $ns[7] = 0x43; 
                $ns[8] = 0x41; 
                $ns[9] = 0x50; 
                $ns[10] = 0x45; 
                $ns[11] = 0x32; 
                $ns[12] = 0x2e; 
                $ns[13] = 0x30; 
                $ns[14] = 0x03; 
                $ns[15] = 0x01; 
                $ns[16] = $this->loop & 255; 
                    $ns[17] = $this->loop >> 8; 
                $ns[18] = 0x00; 
                $this->putbytes($ns, 19); 
            } 
            } 
          if($this->use_global_in) { 
            $outtable = $this->global_in; 
            $outsize = $this->global_color_table_size; 
            $outsizecode = $this->global_color_table_sizecode; 
        } else { 
            $outtable = $this->global_out; 
            $outsize = $this->out_color_table_size; 
        } 
        if($this->local_color_table_flag) { 
            if($size == $this->out_color_table_size && !$this->arrcmp($this->local_in, $this->global_out, $size)) { 
                $outtable = $global_out; 
                $outsize = $this->out_color_table_size; 
            } else { 
                $outtable = $this->local_in; 
                $outsize = $size; 
                $outsizecode = $sizecode; 
            } 
        } 
        $use_trans = false; 
        if($this->transparent) { 
            for($i = 0; $i < $outsize; $i++) { 
                if($outtable[3 * $i] == $this->trans1 && $outtable [3 * $i + 1] == $this->trans2 && $outtable [3 * $i + 2] == $this->trans3) { 
                    break; 
                } 
            } 
            if($i < $outsize) { 
                $transindex = $i; 
                $use_trans = true; 
            } 
        } 
        if($this->delay || $use_trans) { 
            $this->buffer[0] = 0x21; 
            $this->buffer[1] = 0xf9; 
            $this->buffer[2] = 0x04; 
            $this->buffer[3] = ($this->disposal << 2) + ($use_trans ? 1 : 0); 
            $this->buffer[4] = $this->delay & 0xff; 
            $this->buffer[5] = ($this->delay & 0xff00) >> 8; 
            $this->buffer[6] = $use_trans ? $transindex : 0; 
            $this->buffer[7] = 0x00; 
            $this->putbytes($this->buffer,8); 
        } 
        $this->buffer[0] = 0x2c; 
        $this->putbytes($this->buffer,1); 
        $head[0] = $this->x & 0xff; 
        $head[1] = ($this->x & 0xff00) >> 8; 
        $head[2] = $this->y & 0xff; 
        $head[3] = ($this->y & 0xff00) >> 8; 
        $head[8] &= 0x40; 
        if($outtable != $this->global_out) { 
            $head[8] |= 0x80; 
            $head[8] |= $outsizecode; 
        } 
        $this->putbytes($head,9); 
        if($outtable != $this->global_out) { 
            $this->putbytes($outtable, (3 * $outsize)); 
        } 
        $this->getbytes(1); 
        $this->putbytes($this->buffer,1); 
        for(;;) { 
            $this->getbytes(1); 
            $this->putbytes($this->buffer,1); 
            if(($u = $this->buffer[0]) == 0) { 
                break; 
            } 
            $this->getbytes($u); 
            $this->putbytes($this->buffer, $u); 
            } 
    } 
    function read_extension() { 
        $this->getbytes(1); 
        switch($this->buffer[0]) { 
            case 0xf9: 
                    $this->getbytes(6); 
                   break; 
            case 0xfe: 
                    for(;;) { 
                    $this->getbytes(1); 
                            if(($u = $this->buffer[0]) == 0) { 
                            break; 
                        } 
                    $this->getbytes($u); 
                    } 
                break; 
            case 0x01: 
                    $this->getbytes(13); 
                    for(;;) { 
                    $this->getbytes(0); 
                            if(($u = $this->buffer[0]) == 0) { 
                            break; 
                        } 
                    $this->getbytes($u); 
                    } 
                break; 
                   case 0xff: 
                    $this->getbytes(9); 
                    $this->getbytes(3); 
                    for(;;) { 
                    $this->getbytes(1); 
                            if(!$this->buffer[0]) { 
                                break; 
                            } 
                            $this->getbytes($this->buffer[0]); 
                        } 
                break; 
            default: 
                    for(;;) { 
                    $this->getbytes(1); 
                        if(!$this->buffer[0]) { 
                            break; 
                        } 
                    $this->getbytes($this->buffer[0]); 
                } 
            } 
    } 
    function arrcmp($b, $s, $l) { 
        for($i = 0; $i < $l; $i++) { 
            if($s{$i} != $b{$i}) { 
                return false; 
            } 
        } 
        return true; 
    } 
    function getbytes($l) { 
        for($i = 0; $i < $l; $i++) { 
            if($this->mod == 'C_FILE') { 
                    $bin = unpack('C*', fread($this->fin, 1)); 
                    $this->buffer[$i] = $bin[1]; 
                } elseif($this->mod == 'C_MEMORY') { 
                        $bin = unpack('C*', substr($this->fin, $this->ch, 1)); 
                        $this->buffer[$i] = $bin[1]; 
                        $this->ch++; 
                } 
        } 
        return $this->buffer; 
    } 
    function putbytes($s, $l) { 
        for($i = 0; $i < $l; $i++) { 
            $this->fout .= pack('C*', $s[$i]); 
        } 
    } 
    function getAnimation() { 
        return $this->fout; 
    } 
} 
?>
PHP 相关文章推荐
WINXP下apache+php4+mysql
Nov 25 PHP
在普通HTTP上安全地传输密码
Jul 21 PHP
DISCUZ 论坛管理员密码忘记的解决方法
May 14 PHP
PHP中执行MYSQL事务解决数据写入不完整等情况
Jan 07 PHP
php提示Failed to write session data错误的解决方法
Dec 17 PHP
PHP中的替代语法介绍
Jan 09 PHP
yii权限控制的方法(三种方法)
Dec 28 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
什么是PHP文件?如何打开PHP文件?
Jun 27 PHP
PHP实现打包下载文件的方法示例
Oct 07 PHP
php7函数,声明,返回值等新特性介绍
May 25 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
Jun 04 PHP
深入HTTP响应状态码速查表的详解
Jun 07 #PHP
探讨如何把session存入数据库
Jun 07 #PHP
基于PHP对XML的操作详解
Jun 07 #PHP
关于初学PHP时的知识积累总结
Jun 07 #PHP
基于PHP常用字符串的总结(待续)
Jun 07 #PHP
解析php中call_user_func_array的作用
Jun 07 #PHP
简单的cookie计数器实现源码
Jun 07 #PHP
You might like
php获取地址栏信息的代码
2008/10/08 PHP
基于pear auth实现登录验证
2010/02/26 PHP
PHP程序员基本要求和必备技能
2014/05/09 PHP
PHP实现图片裁剪、添加水印效果代码
2014/10/01 PHP
javascript入门·动态的时钟,显示完整的一些方法,新年倒计时
2007/10/01 Javascript
jQuery Autocomplete自动完成插件
2010/07/17 Javascript
javascript标签在页面中的位置探讨
2013/04/11 Javascript
浅析ajax请求json数据并用js解析(示例分析)
2013/07/13 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
2015/05/25 Javascript
TypeScript 中接口详解
2015/06/19 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
判断输入的字符串是否是日期格式的简单方法
2016/07/11 Javascript
Javascript使用uploadify来实现多文件上传
2016/11/16 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
ES6中数组array新增方法实例总结
2017/11/07 Javascript
解决vue接口数据赋值给data没有反应的问题
2018/08/27 Javascript
详谈js的变量提升以及使用方法
2018/10/06 Javascript
vue src动态加载请求获取图片的方法
2018/10/17 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
2018/11/13 Javascript
小程序页面动态配置实现方法
2019/02/05 Javascript
微信小程序文章详情页跳转案例详解
2019/07/09 Javascript
原生JS实现汇率转换功能代码实例
2020/05/13 Javascript
微信小程序实现简单文字跑马灯
2020/05/26 Javascript
Python装饰器的函数式编程详解
2015/02/27 Python
Python通过Django实现用户注册和邮箱验证功能代码
2017/12/11 Python
Python PIL库图片灰化处理
2020/04/07 Python
tensorflow常用函数API介绍
2020/04/19 Python
Spark处理数据排序问题如何避免OOM
2020/05/21 Python
HTML5离线应用与客户端存储的实现
2018/05/03 HTML / CSS
门诊挂号室室长岗位职责
2013/11/27 职场文书
企业总经理任命书
2014/06/05 职场文书
节约每一滴水演讲稿
2014/09/09 职场文书
职工擅自离岗检讨书
2014/09/23 职场文书
服务行业标语口号
2015/12/26 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书
HTML+CSS制作心跳特效的实现
2021/05/26 HTML / CSS