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加速 eAccelerator配置和使用指南
Jun 05 PHP
php判断变量类型常用方法
Apr 24 PHP
PHP+Mysql日期时间如何转换(UNIX时间戳和格式化日期)
Jul 15 PHP
探讨GDFONTPATH能否被winxp下的php支持
Jun 21 PHP
thinkphp的c方法使用示例
Feb 24 PHP
php+mysql实现用户注册登陆的方法
Jan 03 PHP
php使用curl打开https网站的方法
Jun 17 PHP
PHP类和对象相关系统函数与运算符小结
Sep 28 PHP
php+redis在实际项目中HTTP 500: Internal Server Error故障排除
Feb 05 PHP
Django 中 cookie的使用
Aug 17 PHP
零基础php编程好学吗
Oct 11 PHP
PHP命名空间(namespace)原理与用法详解
Dec 11 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
全国FM电台频率大全 - 10 江苏省
2020/03/11 无线电
php笔记之:php数组相关函数的使用
2013/04/26 PHP
深入php处理整数函数的详解
2013/06/09 PHP
浅析PHP 按位与或 (^ 、&amp;)
2013/06/21 PHP
一个经典实用的PHP图像处理类分享
2014/11/18 PHP
php实现的数组转xml案例分析
2019/09/28 PHP
在javascript中对于DOM的加强
2013/04/11 Javascript
javascript数组去重方法终极总结
2014/06/05 Javascript
jQuery中size()方法用法实例
2014/12/27 Javascript
JavaScript实现更改网页背景与字体颜色的方法
2015/02/02 Javascript
JavaScript+html5 canvas实现图片破碎重组动画特效
2016/02/22 Javascript
javascript实现任务栏消息提示的简单实例
2016/05/31 Javascript
sencha ext js 6 快速入门(必看)
2016/06/01 Javascript
JS实现简单的天数计算器完整实例
2017/04/28 Javascript
JS设计模式之命令模式概念与用法分析
2018/02/06 Javascript
JS使用iView的Dropdown实现一个右键菜单
2019/05/06 Javascript
node.js实现上传文件功能
2019/07/15 Javascript
微信小程序修改checkbox的样式代码实例
2020/01/21 Javascript
vue 遮罩层阻止默认滚动事件操作
2020/07/28 Javascript
Nuxt的路由配置和参数传递方式
2020/11/06 Javascript
Vue2.x-使用防抖以及节流的示例
2021/03/02 Vue.js
十分钟利用Python制作属于你自己的个性logo
2018/05/07 Python
在Pycharm中对代码进行注释和缩进的方法详解
2019/01/20 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
Windows下实现将Pascal VOC转化为TFRecords
2020/02/17 Python
python之生成多层json结构的实现
2020/02/27 Python
Python的PIL库中getpixel方法的使用
2020/04/09 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
video结合canvas实现视频在线截图功能
2018/06/25 HTML / CSS
Vision Directa智利眼镜网:框架眼镜、隐形眼镜和名牌太阳眼镜
2016/11/23 全球购物
租租车:国际租车、美国租车、欧洲租车、特价预订国外租车(中文服务)
2018/03/28 全球购物
《画》教学反思
2014/04/14 职场文书
班主任对学生的评语
2014/04/26 职场文书
民政局副局长民主生活会个人对照检查材料
2014/09/19 职场文书
总结几个非常实用的Python库
2021/06/26 Python
python字符串的一些常见实用操作
2022/04/06 Python