0

我正在尝试将 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_readinfo_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);
}
4

1 回答 1

3

你不能。libpng 旨在将 PNG 数据视为流,因此它按顺序逐个解码块。不确定为什么需要跳过 APNG 帧。就像在视频格式中一样,一帧可能存储为“前一帧之后发生的变化”,而不是全帧,因此您可能也需要前一帧。

这些代码示例可能有用: https ://sourceforge.net/projects/apng/files/libpng/examples/

于 2015-01-06T07:56:03.427 回答