我正在尝试将 libpng/apng 移植到 Android 平台,使用带有 apng 补丁的 libpng 来读取动画 png 文件。
我的问题是我没有找到在 png.h 中声明的任何“跳过”方法。我想要做的是直接跳转到特定的帧。但是除非我从头开始阅读并为前面的每一帧执行 png_read_frame_head() 和 png_read_image() ,否则我无法获得正确的结果。
有没有什么方法可以通过指定索引来跳转到特定的帧,而无需提前读取所有帧信息/数据?
以下代码来自 apng 示例http://littlesvr.ca/apng/tutorial/x57.html您可以看到它循环读取 apng 文件。而且您似乎必须调用 png_read_frame_head() 和 png_read_image() 才能更新png_ptr_read和info_ptr_read中的内部信息。因此,如果有任何方法可以简单地修改这两个结构以更正为读取特定帧准备的信息,那么我的问题就解决了。
for(count = 0; count < png_get_num_frames(png_ptr_read, info_ptr_read); count++)
{
sprintf(filename, "extracted-%02d.png", count);
newImage = fopen(filename, "wb");
if(newImage == NULL)
fatalError("couldn't create png for writing");
writeSetup(newImage, &png_ptr_write, &info_ptr_write);
if(setjmp(png_ptr_write->jmpbuf))
fatalError("something didn't work, jump 2");
png_read_frame_head(png_ptr_read, info_ptr_read);
if(png_get_valid(png_ptr_read, info_ptr_read, PNG_INFO_fcTL))
{
png_get_next_frame_fcTL(png_ptr_read, info_ptr_read,
&next_frame_width, &next_frame_height,
&next_frame_x_offset, &next_frame_y_offset,
&next_frame_delay_num, &next_frame_delay_den,
&next_frame_dispose_op, &next_frame_blend_op);
}
else
{
/* the first frame doesn't have an fcTL so it's expected to be hidden,
* but we'll extract it anyway */
next_frame_width = png_get_image_width(png_ptr_read, info_ptr_read);
next_frame_height = png_get_image_height(png_ptr_read, info_ptr_read);
}
writeSetup2(png_ptr_read, info_ptr_read, png_ptr_write, info_ptr_write,
next_frame_width, next_frame_height);
png_write_info(png_ptr_write, info_ptr_write);
png_read_image(png_ptr_read, rowPointers);
png_write_image(png_ptr_write, rowPointers);
png_write_end(png_ptr_write, NULL);
png_destroy_write_struct(&png_ptr_write, &info_ptr_write);
fclose(newImage);
printf("extracted frame %d into %s\n", count, filename);
}