2015-01-06 1 views
0

libpng/apng를 Android 플랫폼에 포팅하려고합니다. apng 패치가있는 libpng를 사용하여 애니메이션 된 png 파일을 읽으려고합니다.apng 패치로 libpng에서 'SKIP'/ 'SEEK'동작을 수행하는 방법

제 질문은 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); 
} 
+0

더 나은 당신이 당신의 답변을 – VicJordan

답변

2

수 없습니다. libpng는 PNG 데이터를 스트림으로 처리하도록 설계되었으므로 청크를 순차적으로 하나씩 디코딩합니다. 왜 APNG 프레임을 건너 뛰어야하는지 잘 모르겠습니다. 비디오 포맷과 마찬가지로 하나의 프레임이 전체 프레임 대신 "이전 프레임 이후에 변경된 것"으로 저장 될 수 있으므로 이전 프레임도 필요할 수 있습니다.

이 코드 예제는 유용 할 수 있습니다 : https://sourceforge.net/projects/apng/files/libpng/examples/

+0

감사를 시도 어떤 코드를 추가, 일부 APNG는 disposeOP = 0 blendOP = 0, 생략하는 것이 안전하므로 사용합니다. 그리고 비디오에서 변환 한 APNG는 종종이 카테고리에 속합니다. 귀하의 답변에 투표 할 수는 있지만 기술적으로 받아 들일 수는 없습니다. – Robin

+0

disposeOP = 0 및 blendOP = 0 인 경우에도 해당 프레임 (직사각형) 크기는 전체 프레임보다 작을 수 있습니다. 확실히하려면 프레임 헤더를 읽어야합니다. 그러나 libpng는 프레임 헤더를 순서없이 읽는 방법을 제공하지 않습니다. 어려운 일을하고 싶다면, (libpng없이) PNG 청크를 스스로 처리하고 다른 모든 것을 무시한 채로 acTL 청크를 읽을 수 있습니다. IDAT에 색인을 생성하고 fdAT를 다시 작성하면 전체적으로 얇아 질 수는 있지만 복잡 할 수 있습니다. – maxst

+0

예, 완전히 그 접근법을 이해합니다. 그러나 아무도 바퀴를 재발견하고 싶지 않습니다. – Robin