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中利用substr_replace将指定两位置之间的字符替换为*号
Jan 27 PHP
php中使用addslashes函数报错问题的解决方法
Feb 06 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
Apr 26 PHP
php htmlspecialchars()与shtmlspecialchars()函数的深入分析
Jun 05 PHP
php中如何判断一个网页请求是ajax请求还是普通请求
Aug 10 PHP
php格式化日期和时间格式化示例分享
Feb 24 PHP
在html文件中也可以执行php语句的方法
Apr 09 PHP
详解WordPress开发中用于获取分类及子页面的函数用法
Jan 08 PHP
php实现的xml操作类
Jan 15 PHP
PHP检测用户是否关闭浏览器的方法
Feb 14 PHP
php组合排序简单实现方法
Oct 15 PHP
php定期拉取数据对比方法实例
Sep 22 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/04/09 日漫
smarty实现多级分类的方法
2014/12/05 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
2015/11/04 PHP
CSS常用网站布局实例
2008/04/03 Javascript
js脚本实现数据去重
2014/11/27 Javascript
JavaScript创建闭包的两种方式的优劣与区别分析
2015/06/22 Javascript
JS实现具备延时功能的滑动门菜单效果
2015/09/17 Javascript
js实现碰撞检测特效代码分享
2016/10/16 Javascript
Bootstrap框架的学习教程详解(二)
2016/10/18 Javascript
jQuery日期范围选择器附源码下载
2017/05/23 jQuery
js判断数组是否包含某个字符串变量的实例
2017/11/24 Javascript
详解如何使用babel进行es6文件的编译
2018/05/29 Javascript
一个Java程序猿眼中的前后端分离以及Vue.js入门(推荐)
2019/04/19 Javascript
解决layui富文本编辑器图片上传无法回显的问题
2019/09/18 Javascript
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
2021/02/26 Vue.js
使用python检测手机QQ在线状态的脚本代码
2013/02/10 Python
python的tkinter布局之简单的聊天窗口实现方法
2014/09/03 Python
python中关于数据类型的学习笔记
2020/07/19 Python
详解Python yaml模块
2020/09/23 Python
Django用户认证系统如何实现自定义
2020/11/12 Python
eBay加拿大站:eBay.ca
2019/06/20 全球购物
澳大利亚礼品篮网站:Macarthur Baskets
2019/10/14 全球购物
Bluebella德国官网:英国性感内衣和睡衣品牌
2019/11/08 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
销售部主管岗位职责
2013/12/18 职场文书
办公室主任岗位承诺书
2014/05/29 职场文书
技校毕业生自荐信
2014/06/03 职场文书
机关领导干部作风整顿整改措施
2014/09/19 职场文书
离婚协议书包括哪些内容
2014/10/16 职场文书
贴吧吧主申请感言
2015/08/03 职场文书
保护环境建议书作文500字
2015/09/14 职场文书
2019年销售人员的职业生涯规划书
2019/03/25 职场文书
竞选稿之小学班干部
2019/10/31 职场文书
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android
Windows server 2016服务器基本设置
2022/08/14 Servers