2013-02-19 3 views
1

У меня возникли проблемы с загрузкой определенных изображений png. Вот некоторые полезные образы.Как загрузить Photoshop png с помощью LIBPNG?

  1. Изображение # 1 www.silexars.com/image.png (не загружает должным образом)
  2. Изображение # 2 www.silexars.com/image2.png (Нагрузки прекрасные)
  3. Скриншот изображения # 1 визуализации с OpenGL http://www.silexars.com/screenshot.jpg
  4. Снимок экрана PNG Analyzer с обоих изображений Открывание: 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);` 

См «вно/gregbook/readpng2.c», то есть распространенный с libpng для примером этого.

ОБНОВЛЕНИЕ: кусок cHRM не обязательно является непоследовательным. Последняя версия ImageMagick сообщает, что она несовместима, но, похоже, это ошибка в ImageMagick. Тем не менее, рекомендуется использовать png_set_keep_unknown_chunks(), чтобы избежать ненужной обработки вспомогательных фрагментов, которые вы не будете использовать.

Смежные вопросы