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 相关文章推荐
VFP与其他应用程序的集成
Oct 09 PHP
php 将字符串按大写字母分隔成字符串数组
Apr 30 PHP
php $_SERVER[&quot;REQUEST_URI&quot;]获取值的通用解决方法
Jun 21 PHP
php中session过期时间设置及session回收机制介绍
May 05 PHP
PHP+Mysql+Ajax+JS实现省市区三级联动
May 23 PHP
codeigniter上传图片不能正确识别图片类型问题解决方法
Jul 25 PHP
php针对cookie操作的队列操作类实例
Dec 10 PHP
PHP截取指定图片大小的方法
Dec 10 PHP
PHP图像处理类库MagickWand用法实例分析
May 21 PHP
Yii的Srbac插件用法详解
Jul 14 PHP
基于php判断客户端类型
Oct 14 PHP
Android AsyncTack 异步任务实例详解
Nov 02 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
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
中国的第一台收音机
2021/03/01 无线电
一个简单的自动发送邮件系统(三)
2006/10/09 PHP
php导出word格式数据的代码实例
2013/11/25 PHP
采用ThinkPHP中F方法实现快速缓存实例
2014/06/13 PHP
PHP获取MySql新增记录ID值的3种方法
2014/06/24 PHP
php的闭包(Closure)匿名函数初探
2016/02/14 PHP
ThinkPHP3.2.2实现持久登录(记住我)功能的方法
2016/05/16 PHP
PHP安装BCMath扩展的方法
2019/02/13 PHP
textarea 控制输入字符字节数(示例代码)
2013/12/27 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
javascript简单比较日期大小的方法
2016/01/05 Javascript
jQuery1.9+中删除了live以后的替代方法
2016/06/17 Javascript
jQuery实现ajax的叠加和停止(终止ajax请求)
2016/08/08 Javascript
Bootstrap列表组学习使用
2017/02/09 Javascript
使用JavaScript根据图片获取条形码的方法
2017/07/04 Javascript
在Swiper内如何制作CSS3动画效果示例代码
2017/12/07 Javascript
小程序实现带年月选取效果的日历
2018/06/27 Javascript
vue项目查看vue版本及cli版本的实现方式
2020/10/24 Javascript
Python3 循环语句(for、while、break、range等)
2017/11/20 Python
python爬虫获取百度首页内容教学
2018/12/23 Python
浅谈Python批处理文件夹中的txt文件
2019/03/11 Python
Python read函数按字节(字符)读取文件的实现
2019/07/03 Python
Python实现子类调用父类的初始化实例
2020/03/12 Python
Python tkinter之ComboBox(下拉框)的使用简介
2021/02/05 Python
高三自我鉴定
2013/10/23 职场文书
资产经营总监岗位职责范文
2013/12/01 职场文书
年终总结会主持词
2014/03/25 职场文书
群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
假期安全教育广播稿
2014/10/04 职场文书
2014年纠风工作总结
2014/12/08 职场文书
企业2014年度工作总结
2014/12/10 职场文书
2014年纳税评估工作总结
2014/12/23 职场文书
英文升职感谢信
2015/01/23 职场文书
教你利用python实现企业微信发送消息
2021/05/23 Python
Pytorch数据读取之Dataset和DataLoader知识总结
2021/05/23 Python