Как выполнить действие 'SKIP'/'SEEK' в libpng с патчем apng
Я пытаюсь портировать libpng/apng на платформу Android, используя libpng с патчем apng для чтения анимированного файла 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);
}
1 ответ
Ты не можешь libpng был разработан для обработки данных PNG как потока, поэтому он последовательно декодирует фрагменты, один за другим. Не уверен, почему вам нужно пропустить кадры APNG. Как и в видеоформатах, один кадр может быть сохранен как "то, что изменилось после предыдущего кадра", а не как полный кадр, поэтому вам также могут понадобиться предыдущие кадры.
Эти примеры кода могут быть полезны: https://sourceforge.net/projects/apng/files/libpng/examples/