我想把一个动态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>