2013-02-19 71 views
1

我正在加載一些特定的PNG圖像時遇到一些問題。這裏有一些有用的圖像。如何用LIBPNG加載Photoshop PNG?

  1. 圖像#1 www.silexars.com/image.png(不正確加載)
  2. 影像#2 www.silexars.com/image2.png(載荷細)
  3. 截圖圖像的#1渲染使用OpenGL PNG分析儀http://www.silexars.com/screenshot.jpg
  4. 截圖與兩個圖像打開: http://www.silexars.com/screenshot.png圖片#1 @左,圖片#2 @ 右鍵

我注意到左圖像有一個名爲cHRM的塊,我相信我必須以某種方式將其轉換。 有人可以幫我解決這個問題嗎?

,我使用加載PNG文件的代碼是:

uint8 Graphics::Image::loadPNG(FILE *fp) { 
uint8 header[8]; 
fread(header,sizeof(header),1,fp); 
if (png_sig_cmp(header,0,sizeof(header))) return INVALID_FILE; 
png_structp png; 
png_infop info; 

png = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0); 
if (!png) return FAILURE; 
info = png_create_info_struct(png); 
if (!info) { 
    png_destroy_read_struct(&png,0,0); 
    return FAILURE; 
} 

png_init_io(png,fp);\ 
png_set_sig_bytes(png,sizeof(header)); 

png_read_info(png,info); 

delete[] data; 
data = 0; 

int32 bitdepth,colortype; 
png_get_IHDR(png,info,&width,&height,&bitdepth,&colortype,0,0,0); 

if (colortype == PNG_COLOR_TYPE_PALETTE) { 
    png_set_palette_to_rgb(png); 
} 
if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8) { 
    png_set_expand_gray_1_2_4_to_8(png); 
} 
if (colortype == PNG_COLOR_TYPE_GRAY || colortype == PNG_COLOR_TYPE_GRAY_ALPHA) { 
    png_set_gray_to_rgb(png); 
} 
if (png_get_valid(png, info, PNG_INFO_tRNS)) { 
    png_set_tRNS_to_alpha(png); 
} 
if (colortype == PNG_COLOR_TYPE_RGB) { 
    png_set_filler(png, 0xff, PNG_FILLER_AFTER); 
} 
if (bitdepth == 16) { 
    png_set_strip_16(png); 
} 
if (bitdepth < 8) 
    png_set_packing(png); 

png_read_update_info(png,info); 
png_get_IHDR(png,info,&width,&height,0,0,0,0,0); 

int32 rowbytes = png_get_rowbytes(png,info); 

std::cout << rowbytes/bpp << std::endl; 

data = new uint8[rowbytes*height]; 
png_bytep *row_pointers = new png_bytep[height*sizeof(png_bytep)]; 
for (int i = 0; i < height; i++) 
    row_pointers[height-1-i] = data + i * rowbytes; 

png_read_image(png, row_pointers); 

png_read_end(png,0); 

delete[] row_pointers; 
png_destroy_read_struct(&png,&info,0); 
return OK; 
} 

希望的信息就足夠了。但是如果你需要任何額外的數據,請問我。

回答

1

第一張圖像中的cHRM塊與iCCP塊中包含的顏色配置文件不一致。最好忽略cHRM塊。但是你的代碼已經忽略了cHRM和iCCP塊。您可以使用png_set_keep_unknown_chunks()來完全忽略它們,以防其中一個導致您遇到的麻煩(即使您的代碼忽略它們,libpng也會處理它們,除非您使用png_set_keep_unknown_chunks()告訴libpng它們不應該被處理)。

例如,因爲你是忽略所有附屬塊在您的應用程序,告訴了libpng沒有,甚至對其進行處理:

` 
    #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 
    /* prepare the reader to ignore all recognized chunks whose data won't be 
    * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT, 
    * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */ 
    { 
     /* These byte strings were copied from png.h. If a future libpng 
     * version recognizes more chunks, add them to this list. If a 
     * future version of readpng2.c recognizes more chunks, delete them 
     * from this list. */ 
     static /* const */ png_byte chunks_to_ignore[] = { 
      99, 72, 82, 77, '\0', /* cHRM */ 
      104, 73, 83, 84, '\0', /* hIST */ 
      105, 67, 67, 80, '\0', /* iCCP */ 
      105, 84, 88, 116, '\0', /* iTXt */ 
      111, 70, 70, 115, '\0', /* oFFs */ 
      112, 67, 65, 76, '\0', /* pCAL */ 
      112, 72, 89, 115, '\0', /* pHYs */ 
      115, 66, 73, 84, '\0', /* sBIT */ 
      115, 67, 65, 76, '\0', /* sCAL */ 
      115, 80, 76, 84, '\0', /* sPLT */ 
      115, 84, 69, 82, '\0', /* sTER */ 
      116, 69, 88, 116, '\0', /* tEXt */ 
      116, 73, 77, 69, '\0', /* tIME */ 
      122, 84, 88, 116, '\0' /* zTXt */ 
     }; 

     png_set_keep_unknown_chunks(png_ptr, 1 /* PNG_HANDLE_CHUNK_NEVER */, 
      chunks_to_ignore, sizeof(chunks_to_ignore)/5); 
    } 
    #endif` 

與開始的libpng-1.6.0這是一個容易得多。你可以忽略,而不是列出的塊被忽略呼叫除了通過將TRNS塊都 配套塊「-1」 :

` 
    png_set_keep_unknown_chunks(png,PNG_HANDLE_CHUNK_NEVER, -1, NULL, -1);` 

見「的contrib/gregbook/readpng2.c」,也就是用libpng分發給 的一個例子。

更新:cHRM塊不一定是不一致的。 ImageMagick的最新版本報告說它不一致,但這似乎是ImageMagick中的一個錯誤。同樣,使用png_set_keep_unknown_chunks()只是爲了避免不必要的輔助塊的處理,這是一個好主意。

相關問題