gif用到php_用php将动态gif拆分成单帧

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

class 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 '

printf("

图片文件名 %s", $this->imagename);

echo '

foreach($dict as $key => $value)

printf("

%s%s",$value,$this->$key);

printf("

%s", $this->imagename);

for($i=0; $iframe; $i++) {

printf("

帧号 %s",$i);

echo '

foreach($image_dict as $key => $value)

printf("

%s%s",$value,$this->image[$i][$key]);

printf("

?frame=%d", $i);

}

echo "

";

}

/**

* 内部方法 control_extension,由withdraw方法调用

* 输出图象扩展控制段

* 参数

* $frame 数值,图片帧号

* $delay_time 数值,图象停顿时间,单位为百分秒(10ms)

* $disposal_mothod 数值,处置方式

* 返回 无

**/

function control_extension($frame=0, $delay_time=10, $disposal_mothod=0) {

$transparent = $this->image[$frame]['transparecy_index'];

$flag = ($disposal_mothod << 2) | $this->image[$frame]['transparent_flag'];

echo pack("CCCCSCC", 0x21, 0xf9, 4, $flag, $delay_time, $transparent, 0);

}

/**

* 内部方法 image_frame,由withdraw方法调用

* 输出一帧图象

* 参数

* $frame 数值,图片帧号

* $left 数值,图象左边距

* $top 数值,图象上边距

* $colortab 字符串,对比用的全局调色板数据

* 返回 无

**/

function image_frame($frame=0, $left=null, $top=null, $colortab=null) {

if($left == null) $left = $this->image[$frame]['left_position'];

if($top == null) $top = $this->image[$frame]['top_position'];

$flag = $this->image[$frame]['flag'];

$color_table = '';

if($this->image[$frame]['local_color_table_flag']) {

//如图象有局部调色板则取局部调色板

$color_table = $this->image[$frame]['local_color_table'];

}elseif($colortable != null && $colortable != $this->global_color_table) {

//如图象没有局部调色板且全局调色板与对比调色板不同,就把全局调色板设置为局部调色板

$flag &= 0x40; //保留交错标志

$flag |= $this->sort_flag ? 0x20 : 0x00; //设置排序标志

$flag |= 0x80; //设置局部色表标志

$flag |= $this->size_of_global_color_table;

$color_table = $this->global_color_table;

}

$width = $this->image[$frame]['width'];

$height = $this->image[$frame]['height'];

echo pack("CSSSSC", 0x2c, $left, $top, $width, $height, $flag);

echo $color_table;

echo $this->image[$frame]['data'];

}

/**

* 内部方法 image_header,由withdraw方法调用

* 输出图片头

* 参数

* $width 数值,图片宽

* $height 数值,图片高

* 返回 无

**/

function image_header($width=0, $height=0) {

ob_start();

printf("GIF89a%s%s%c%c%c"

, pack("S", $this->logical_screen_width)

, pack("S", $this->logical_screen_height)

, $this->flag

, $this->background_color_index

, $this->pixel_aspect_ratio

);

if($this->global_color_table_flag)

echo $this->global_color_table;

}

/**

* 内部方法 image_end,由withdraw方法调用

* 输出图片尾,并返回图片数据

* 返回 字符串,图片数据

**/

function image_end() {

echo chr(0x3b);

$buf = ob_get_clean();

return $buf;

}

/**

* 公共方法 withdraw

* 生成单帧的图片[文件]

* 参数

* $frame 数值,提取的帧号

* $filename 字符串,目标文件名,缺省为空(不生成文件)

* 返回 字符串,图片数据

**/

function withdraw($frame=0, $filename='') {

if($frame > $this->frame-1) $frame = 0;

$this->image_header();

$this->control_extension($frame);

$this->image_frame($frame);

$buf = $this->image_end();

if(!empty($filename))

file_put_contents($filename, $buf);

return $buf;

}

}

$p = new TGif('old.gif');

//$p->info();

echo $p->withdraw(0, 'hello.gif');

//print_r($p->image);

?>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值