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 相关文章推荐
利用PHP动态生成VRML网页
Oct 09 PHP
兼容firefox,chrome的网页灰度效果
Aug 08 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
Nov 26 PHP
php利用curl抓取新浪微博内容示例
Apr 27 PHP
ThinkPHP添加更新标签的方法
Dec 05 PHP
php将字符串全部转换成大写或者小写的方法
Mar 17 PHP
PHP检测数据类型的几种方法(总结)
Mar 04 PHP
php之可变函数的实例详解
Sep 13 PHP
PHP实现正则匹配所有括号中的内容
Jun 22 PHP
Laravel学习笔记之Artisan命令生成自定义模板的方法
Nov 22 PHP
Yii框架常见缓存应用实例小结
Sep 09 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
Nov 23 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 HTML JavaScript MySQL代码如何互相传值的方法分享
2012/09/30 PHP
php数组转成json格式的方法
2015/03/09 PHP
php上传文件并存储到mysql数据库的方法
2015/03/16 PHP
PHP实现的memcache环形队列类实例
2015/07/28 PHP
PHP safe_mode开启对于PHP系统函数有什么影响
2020/11/10 PHP
用js实现手把手教你月入万刀(转贴)
2007/11/07 Javascript
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
分析Node.js connect ECONNREFUSED错误
2013/04/09 Javascript
iframe窗口高度自适应的又一个巧妙实现思路
2014/04/04 Javascript
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
JS实现将Asp.Net的DateTime Json类型转换为标准时间的方法
2016/08/02 Javascript
JavaScript组合模式学习要点
2016/08/26 Javascript
vue.js将unix时间戳转换为自定义时间格式
2017/01/03 Javascript
微信小程序 生命周期和页面的生命周期详细介绍
2017/01/19 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
jquery tmpl模板(实例讲解)
2017/09/02 jQuery
详解cordova打包成webapp的方法
2017/10/18 Javascript
个人小程序接入支付解决方案
2019/05/23 Javascript
a标签调用js的方法总结
2019/09/05 Javascript
JS实现基本的网页计算器功能示例
2020/01/16 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
Vue实现背景更换颜色操作
2020/07/17 Javascript
python单线程实现多个定时器示例
2014/03/30 Python
python里大整数相乘相关技巧指南
2014/09/12 Python
Python内置函数Type()函数一个有趣的用法
2015/02/18 Python
python实现telnet客户端的方法
2015/04/15 Python
Python3.X 线程中信号量的使用方法示例
2017/07/24 Python
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
python logging日志模块的详解
2017/10/29 Python
python实现批量注册网站用户的示例
2019/02/22 Python
python设计微型小说网站(基于Django+Bootstrap框架)
2019/07/08 Python
使用Pyinstaller转换.py文件为.exe可执行程序过程详解
2019/08/06 Python
初婚初育证明
2014/01/14 职场文书
《小猫刮胡子》教学反思
2014/02/21 职场文书
工作求职自荐信
2014/06/13 职场文书
学习十八大标语
2014/10/09 职场文书