目前项目里有一需求,需要用php动态替换flash中图片(因为是flash lite 1.1,所以不能在flash中替换),思路是先将flash读取成2进制流,然后将其中的图片信息替换掉,替换后直接在页面输出,显示新的flash。现在的问题是php对2进制流操作的支持非常弱,请问各位大侠这个有没可能实现?以下是c的实现
int main(int argc, char **argv) {
char *program_name = argv[0];
swf_file_t *swf_file;
swf_block_t *block;
struct stat filestat;
long jpeg_size;
unsigned char *data;
FILE *fp;
if (argc != 4) {
usage(program_name);
return EXIT_FAILURE;
}
char *file_name = argv[1];
int jpeg_id = atoi(argv[2]);
char *jpeg_file = argv[3];
swf_file = load_swf_file(file_name);
if (! swf_file) {
usage(program_name);
fprintf(stderr, "Can't load swf file\n");
return EXIT_FAILURE;
} printf("search jpeg id\n");
for(block = swf_file->block; block; block = block->next) {
if (block->tag == 6) { // DefineBitsJPEG
data = block->body;
int id = LE_VALUE_2BYTE(data);
printf("id=0x%x\n", id);
if (id == jpeg_id) {
break;
}
}
}
if (! block) {
fprintf(stderr, "not found such jpeg id(%d)", jpeg_id);
exit (1);
}
/* replace jpeg file */ if(stat(jpeg_file, &filestat)) {
perror("stat jpegfile");
exit(1);
}
jpeg_size = filestat.st_size;
fp = fopen(jpeg_file, "rb");
if (! fp) {
perror("open jpegfile");
exit(1);
}
data = calloc(2 + jpeg_size, 1);
LE_BYTES_USHORT(data, jpeg_id);
fread(data + 2, jpeg_size, 1, fp);
fclose(fp);
block->length = jpeg_size;
free(block->body);
block->body = data;
/* output */
save_swf_file("test.swf", swf_file);
return EXIT_SUCCESS;
}
int main(int argc, char **argv) {
char *program_name = argv[0];
swf_file_t *swf_file;
swf_block_t *block;
struct stat filestat;
long jpeg_size;
unsigned char *data;
FILE *fp;
if (argc != 4) {
usage(program_name);
return EXIT_FAILURE;
}
char *file_name = argv[1];
int jpeg_id = atoi(argv[2]);
char *jpeg_file = argv[3];
swf_file = load_swf_file(file_name);
if (! swf_file) {
usage(program_name);
fprintf(stderr, "Can't load swf file\n");
return EXIT_FAILURE;
} printf("search jpeg id\n");
for(block = swf_file->block; block; block = block->next) {
if (block->tag == 6) { // DefineBitsJPEG
data = block->body;
int id = LE_VALUE_2BYTE(data);
printf("id=0x%x\n", id);
if (id == jpeg_id) {
break;
}
}
}
if (! block) {
fprintf(stderr, "not found such jpeg id(%d)", jpeg_id);
exit (1);
}
/* replace jpeg file */ if(stat(jpeg_file, &filestat)) {
perror("stat jpegfile");
exit(1);
}
jpeg_size = filestat.st_size;
fp = fopen(jpeg_file, "rb");
if (! fp) {
perror("open jpegfile");
exit(1);
}
data = calloc(2 + jpeg_size, 1);
LE_BYTES_USHORT(data, jpeg_id);
fread(data + 2, jpeg_size, 1, fp);
fclose(fp);
block->length = jpeg_size;
free(block->body);
block->body = data;
/* output */
save_swf_file("test.swf", swf_file);
return EXIT_SUCCESS;
}
<?php
// swf文件的MIME
header('Content-type: application/x-shockwave-flash');// 输出给浏览器的swf文件名
header('Content-Disposition: attachment; filename="target.swf"');// 需要显示的swf文件,可以动态添加
readfile('target.swf');
?>
看来只能用swfmill了,效率低点也没办法了
很简单的问题,都被弄复杂了。替换图片的话,同理,只不过PHP输出图片就可以了。
直接翻译 c 语言代码为 php 代码即可
把上面的流输出到 SWF 即可
所以操作要非常小心,如果替换正确的话 对于原帧内二进制的图片信息替换为 非相同长度二进制图片流时候 swf还是可以正常显示的在 c里 load_swf_file 确实对它进行了重构,但不是对每帧。只是得到它的结构,比如哪一部分是图片之类的,图片类型什么的。
(swfmill可以将flash转换成xml,我们再将其中的图片内容替换掉,然后再通过swfmill将xml转换成flash)