• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

用php将动态gif拆分成单帧

php 搞代码 4年前 (2022-01-25) 22次浏览 已收录 0个评论
文章目录[隐藏]

我想把一个动态gif拆分成一帧一帧的 然后对单帧进行修改后再合并起来 在网上找了一段代码 但是在拆分成单帧的时候就出了问题 但是不知道错在哪里了 请各位大虾帮忙看看 代码如下

<code><?phpclass TGif {  var $signature; //签名  var $version;  //版本  var $image = array();  var $frame = 0;  var $buffer = ''; //图片数据缓存区  /**   * 内部方法 next   * 从图片数据缓冲区读取指定长度的字符串   * 参数 $len 数值,读取的长度,确省为1   * 返回 长度为1时返回码值   *      其他返回字符串   **/  function next($len=1) {    $ch = substr($this->buffer, 0, $len);    $this->buffer = substr($this->buffer, $len);    if($len == 1)        return ord($ch);    return $ch;  }  /**   * 内部方法 get_number   * 从图片数据缓冲区读取一个整数   * 参数 无   * 返回 整数   **/  function get_number() {    $t = unpack("Sn", $this->next(2));    return $t['n'];  }  /**   * 构造函数   * 参数 $imagename 字符串,图片文件名或图片数据   * 返回 无   **/  function TGif($imagename="images/xzn.gif") {    $this->image = array();    $this->frame = 0;    if(is_file($imagename)) {        $this->imagename = $imagename;        $this->buffer = @file_get_contents($imagename)            or trigger_error("$imagename 打不开", E_USER_ERROR);    }else {        substr($imagename, 0, 3) == 'GIF' or            trigger_error("$imagename 不存在或不是GIF格式图片", E_USER_ERROR);        $this->buffer = $imagename;        $this->imagename = '未命名';    }    $this->get_header();    while(strlen($this->buffer)) {        switch($this->next()) {            case 0x21: //图象扩展描述符                $this->get_extension_introducer();                break;            case 0x2c: //图象描述符                $this->get_image_descriptor();                break;            case 0x3b: //GIF数据流结束                return;        }    }  }  /**   * 内部方法 get_color_table   * 读取调色板数据   **/  function get_color_table($num) {    return $this->next(3*pow(2,$num+1));  }  /**   * 内部方法 get_header   * 读取头信息   **/  function get_header() {    $this->signature = $this->next(3);    //类型标识gif    if($this->signature != 'GIF')        trigger_error("$this->imagename 不是GIF格式图片", E_USER_ERROR);    $this->version = $this->next(3);    //版本标识    $this->logical_screen_width = $this->get_number();    //逻辑屏幕宽    $this->logical_screen_height = $this->get_number();    //逻辑屏幕高    $this->flag = $flag = $this->next();    $this->global_color_table_flag = ($flag & 0x80) > 0;    //是否有全局调色板    $this->color_resolution = (($flag >> 4) & 0x07) + 1;    //彩色分辨率    $this->sort_flag = ($flag & 0x08) > 0;            //调色板是否排序    $this->size_of_global_color_table = $flag & 0x07;    //全局色板大小,2的乘方的指数    $this->background_color_index = $this->next();        //背景色索引    $this->pixel_aspect_ratio = $this->next();         //像素纵横比    if($this->global_color_table_flag)        $this->global_color_table = $this->get_color_table($this->size_of_global_color_table);  }  /**   * 内部方法 get_image_descriptor   * 读取图片信息   **/  function get_image_descriptor() {    $image['left_position'] = $this->get_number();    $image['top_position'] = $this->get_number();    $image['width'] = $this->get_number();    $image['height'] = $this->get_number();    $image['flag'] = $flag = $this->next();    $image['local_color_table_flag'] = ($flag & 0x80) > 0;    //局部色表    $image['interlace_flag'] = ($flag & 0x40) > 0;        //交错    $image['local_sort_flag'] = ($flag & 0x20) > 0;        //色表是否排序    $image['size_of_local_color_table'] = $flag & 0x07;    //局部色表大小    if($image['local_color_table_flag'])        $image['local_color_table'] = $this->get_color_table($image['size_of_local_color_table']);    $image['data'] = $this->get_table_based_image_data();    $this->image[$this->frame] = array_merge($this->image[$this->frame], $image);    $this->frame++;  }  /**   * 内部方法 get_table_based_image_data   * 读取图象数据   **/  function get_table_based_image_data() {    $table_based_image_data_size = 0;    $table_based_image_data = chr($this->next());    while($n = $this->next()) {        $table_based_image_data_size += $n;        $table_based_image_data .= chr($n);        $table_based_image_data .= $this->next($n);    }    $table_based_image_data .= chr(0);    return $table_based_image_data;  }  /**   * 内部方法 get_extension_introducer   * 读取图象扩展   **/  function get_extension_introducer() {    switch($this->next()) {        case 0xf9:            $size = $this->next(); //固定为4            $flag = $this->next();            $this->image[$this->frame]['disposal_method'] = ($flag >> 2) & 0x07;            $this->image[$this->frame]['transparent_flag'] = $flag & 0x01;            $this->image[$this->frame]['delay_time'] = $this->get_number();            $this->image[$this->frame]['transparecy_index'] = $this->next();            $this->next();        break;    case 0xfe:        while($this->next() != 0);        break;    case 0x01:        $this->next();        $delay_time = $this->get_number();        $delay_time = $this->get_number();        $delay_time = $this->get_number();        $delay_time = $this->get_number();        $this->next();        $this->next();        $this->next();        $this->next();        while($this->next() != 0);        break;    case 0xff:        $this->application_extension = $this->next($this->next());        while($this->next() != 0);        break;    }  }  /**   * 公共方法 info   * 产生图片信息报告   **/  function info() {    if(isset($_GET['frame'])) {        echo $this->withdraw($_GET['frame']);        exit;    }    $dict = array(        'logical_screen_width' => '图片宽度',        'logical_screen_height' => '图片高度',        'global_color_table_flag' => '全局色表',        'color_resolution' => '彩色分辨率',        'sort_flag' => '排序标志',        'size_of_global_color_table' => '全局色表大小',        'background_color_index' => '背景色索引',        'pixel_aspect_ratio' => '像素纵横比',        'frame' => '帧数',        'application_extension' => '应用程序扩展',        );    $image_dict = array(        'left_position' => '图象左边距',        'top_position' => '图象上边距',        'width' => '图象宽',        'height' => '图象高',        'local_color_table_flag' => '局部色表',        'interlace_flag' => '交错',        'local_sort_flag' => '排序标志',        'size_of_local_color_table' => '局部色表大小',        'delay_time' => '停顿时间',        'disposal_method' => '处置方式',        'transparecy_index' => '透明色索引',        );    echo '<table border>';    printf("<tr><th colspan="2">图片文件名 %s</th></tr>", $this->imagename);    echo '<tr><td><table>';    foreach($dict as $key => $value)        printf("<tr><td>%s</td><td>%s</td></tr>",$value,$this->$key);    printf("</table></td><td></td></tr>",%20$this->imagename);%20%20%20%20for($i=0;%20$iframe;%20$i++)%20{%20%20%20%20%20%20%20%20printf("<tr><th>帧号%20%s</th></tr>",$i);%20%20%20%20%20%20%20%20echo%20'<tr><td><table>';%20%20%20%20%20%20%20%20foreach($image_dict%20as%20$key%20=>%20$value)%20%20%20%20%20%20%20%20%20%20%20%20printf("<tr><td>%s</td><td>%s</td></tr>",$value,$this->image[$i][$key]);%20%20%20%20%20%20%20%20printf("</table></td><td></td></tr>",%20$i);%20%20%20%20}%20%20%20%20echo%20"</table>";%20%20}%20%20/**%20%20%20*%20内部方法%20control_extension,由withdraw方法调用%20%20%20*%20输出图象扩展控制段%20%20%20*%20参数%20%20%20*%20%20$frame%20数值,图片帧号%20%20%20*%20%20$delay_time%20数值,图象停顿时间,单位为百分秒(10ms)%20%20%20*%20%20$disposal_mothod%20数值,处置方式%20%20%20*%20返回%20无%20%20%20**/%20%20function%20control_extension($frame=0,%20$delay_time=10,%20$disposal_mothod=0)%20{%20%20%20%20$transparent%20=%20$this->image[$frame]['transparecy_index'];%20%20%20%20$flag%20=%20($disposal_mothod%20image[$frame]['transparent_flag'];%20%20%20%20echo%20pack("CCCCSCC",%200x21,%200xf9,%204,%20$flag,%20$delay_time,%20$transparent,%200);%20%20}%20%20/**%20%20%20*%20内部方法%20image_frame,由withdraw方法调用%20%20%20*%20输出一帧图象%20%20%20*%20参数%20%20%20*%20%20$frame%20数值,图片帧号%20%20%20*%20%20$left%20数值,图象左边距%20%20%20*%20%20$top%20数值,图象上边距%20%20%20*%20%20$colortab%20字符串,对比用的全局调色板数据%20%20%20*%20返回%20无%20%20%20**/%20%20function%20image_frame($frame=0,%20$left=null,%20$top=null,%20$colortab=null)%20{%20%20%20%20%20%20if($left%20==%20null)%20$left%20=%20$this->image[$frame]['left_position'];%20%20%20%20%20%20if($top%20==%20null)%20$top%20=%20$this->image[$frame]['top_position'];%20%20%20%20$flag%20=%20$this->image[$frame]['flag'];%20%20%20%20$color_table%20=%20'';%20%20%20%20if($this->image[$frame]['local_color_table_flag'])%20{%20%20%20%20%20%20%20%20//如图象有局部调色板则取局部调色板%20%20%20%20%20%20%20%20$color_table%20=%20$this->image[$frame]['local_color_table'];%20%20%20%20}elseif($colortable%20!=%20null%20&&%20$colortable%20!=%20$this->global_color_t<span>@本文来*源gaodai#ma#com搞*!代#%^码$网*</span><textarea>搞gaodaima代码</textarea>able)%20{%20%20%20%20%20%20%20%20//如图象没有局部调色板且全局调色板与对比调色板不同,就把全局调色板设置为局部调色板%20%20%20%20%20%20%20%20$flag%20&=%200x40;%20//保留交错标志%20%20%20%20%20%20%20%20$flag%20|=%20$this->sort_flag%20?%200x20%20:%200x00;%20//设置排序标志%20%20%20%20%20%20%20%20$flag%20|=%200x80;%20//设置局部色表标志%20%20%20%20%20%20%20%20$flag%20|=%20$this->size_of_global_color_table;%20%20%20%20%20%20%20%20$color_table%20=%20$this->global_color_table;%20%20%20%20}%20%20%20%20$width%20=%20$this->image[$frame]['width'];%20%20%20%20$height%20=%20$this->image[$frame]['height'];%20%20%20%20echo%20pack("CSSSSC",%200x2c,%20$left,%20$top,%20$width,%20$height,%20$flag);%20%20%20%20echo%20$color_table;%20%20%20%20echo%20$this->image[$frame]['data'];%20%20}%20%20/**%20%20%20*%20内部方法%20image_header,由withdraw方法调用%20%20%20*%20输出图片头%20%20%20*%20参数%20%20%20*%20%20$width%20数值,图片宽%20%20%20*%20%20$height%20数值,图片高%20%20%20*%20返回%20无%20%20%20**/%20%20function%20image_header($width=0,%20$height=0)%20{%20%20%20%20ob_start();%20%20%20%20%20%20printf("GIF89a%s%s%c%c%c"%20%20%20%20%20%20%20%20%20%20,%20pack("S",%20$this->logical_screen_width)%20%20%20%20%20%20%20%20%20%20,%20pack("S",%20$this->logical_screen_height)%20%20%20%20%20%20%20%20%20%20,%20$this->flag%20%20%20%20%20%20%20%20%20%20,%20$this->background_color_index%20%20%20%20%20%20%20%20%20%20,%20$this->pixel_aspect_ratio%20%20%20%20%20%20%20%20%20%20);%20%20%20%20if($this->global_color_table_flag)%20%20%20%20%20%20%20%20echo%20$this->global_color_table;%20%20}%20%20/**%20%20%20*%20内部方法%20image_end,由withdraw方法调用%20%20%20*%20输出图片尾,并返回图片数据%20%20%20*%20返回%20字符串,图片数据%20%20%20**/%20%20function%20image_end()%20{%20%20%20%20echo%20chr(0x3b);%20%20%20%20$buf%20=%20ob_get_clean();%20%20%20%20return%20$buf;%20%20}%20%20/**%20%20%20*%20公共方法%20withdraw%20%20%20*%20生成单帧的图片[文件]%20%20%20*%20参数%20%20%20*%20%20$frame%20数值,提取的帧号%20%20%20*%20%20$filename%20字符串,目标文件名,缺省为空(不生成文件)%20%20%20*%20返回%20字符串,图片数据%20%20%20**/%20%20function%20withdraw($frame=0,%20$filename='')%20{%20%20%20%20if($frame%20>%20$this->frame-1)%20$frame%20=%200;%20%20%20%20$this->image_header();%20%20%20%20$this->control_extension($frame);%20%20%20%20$this->image_frame($frame);%20%20%20%20$buf%20=%20$this->image_end();%20%20%20%20if(!empty($filename))%20%20%20%20%20%20%20%20%20file_put_contents($filename,%20$buf);%20%20%20%20return%20$buf;%20%20}}$p%20=%20new%20TGif('old.gif');//$p->info();echo $p->withdraw(0, 'hello.gif');//print_r($p->image);?></code>

回复内容:


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:用php将动态gif拆分成单帧
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址