<code><?php
class
TGif {
var
$signature
;
var
$version
;
var
$image
=
array
();
var
$frame
= 0;
var
$buffer
=
''
;
function
next(
$len
=1) {
$ch
=
substr
(
$this
->buffer, 0,
$len
);
$this
->buffer =
substr
(
$this
->buffer,
$len
);
if
(
$len
== 1)
return
ord(
$ch
);
return
$ch
;
}
function
get_number() {
$t
= unpack(
"Sn"
,
$this
->next(2));
return
$t
[
'n'
];
}
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:
return
;
}
}
}
function
get_color_table(
$num
) {
return
$this
->next(3*pow(2,
$num
+1));
}
function
get_header() {
$this
->signature =
$this
->next(3);
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;
$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);
}
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++;
}
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
;
}
function
get_extension_introducer() {
switch
(
$this
->next()) {
case
0xf9:
$size
=
$this
->next();
$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
;
}
}
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><img src=
"%s"
alt=
"用php将动态gif拆分成单帧"
></td>
</tr>",
$this
->imagename);
for
(
$i
=0;
$iframe
;
$i
++) {
printf(
"<tr><th colspan="
2
">帧号 %s</th></tr>"
,
$i
);
echo
'<tr>
<td><table>';
foreach
(
$image_dict
as
$key
=>
$value
)
printf("<tr>
<td>%s</td>
<td>%s</td>
</tr>",
$value
,
$this
->image[
$i
][
$key
]);
printf("</table></td>
<td><img src=
"?frame=%d"
alt=
"用php将动态gif拆分成单帧"
></td>
</tr>",
$i
);
}
echo
"</table>"
;
}
function
control_extension(
$frame
=0,
$delay_time
=10,
$disposal_mothod
=0) {
$transparent
=
$this
->image[
$frame
][
'transparecy_index'
];
$flag
= (
$disposal_mothod
image[
$frame
][
'transparent_flag'
];
echo
pack(
"CCCCSCC"
, 0x21, 0xf9, 4,
$flag
,
$delay_time
,
$transparent
, 0);
}
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'
];
}
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;
}
function
image_end() {
echo
chr
(0x3b);
$buf
= ob_get_clean();
return
$buf
;
}
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'
);
echo
$p
->withdraw(0,
'hello.gif'
);
?>
</code>