2016-11-15 1 views
0

J'utilise la bibliothèque libpng pour charger des fichiers PNG dans un PixelBuffer, qui est simplement un tableau 2-D ou des valeurs RGBA.Chargement des fichiers PNG RVB en image noire

Le code suivant fonctionne pour et l'image contient un canal alpha, mais pas sur une image qui ne contient pas le canal alpha.

PixelBuffer *IOManager::load_png_to_pixel_buffer(const char *file_name) { 
    FILE *infile; 

    char header[8]; 

    bool alphaFlag = false; 


    if ((infile = fopen(file_name, "rb")) == NULL) { 
     std::cout << "Could not open file: " << file_name << std::endl; 
     return nullptr; 
    } 

    fread(header, 1, 8, infile); 


    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 

    if (!png_ptr){ 
     std::cout << "Could not create PNG read struct" << std::endl; 
     return nullptr; 
    } 

    png_infop info_ptr = png_create_info_struct(png_ptr); 

    if (!info_ptr){ 
     std::cout << "Could not create PNG info struct" << std::endl; 
     return nullptr; 
    } 


    png_init_io(png_ptr, infile); 
    png_set_sig_bytes(png_ptr, 8); 

    png_read_info(png_ptr, info_ptr); 

    int width = png_get_image_width(png_ptr, info_ptr); 
    int height = png_get_image_height(png_ptr, info_ptr); 
    png_byte color_type = png_get_color_type(png_ptr, info_ptr); 
    png_byte bit_depth = png_get_bit_depth(png_ptr, info_ptr); 

    if (bit_depth == 16){ 
     png_set_strip_16(png_ptr); 
    } 

    if (color_type == PNG_COLOR_TYPE_PALETTE){ 
     png_set_palette_to_rgb(png_ptr); 
    } 

    if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8){ 
     png_set_expand_gray_1_2_4_to_8(png_ptr); 
    } 

    if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){ 
     png_set_tRNS_to_alpha(png_ptr); 
    } 

    if(color_type == PNG_COLOR_TYPE_RGB || 
     color_type == PNG_COLOR_TYPE_GRAY || 
     color_type == PNG_COLOR_TYPE_PALETTE){ 
     std::cout << "Setting filler" << std::endl; 
     png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); 
    } 

    if(color_type == PNG_COLOR_TYPE_GRAY || 
     color_type == PNG_COLOR_TYPE_GRAY_ALPHA){ 
     png_set_gray_to_rgb(png_ptr); 
    } 

    png_read_update_info(png_ptr, info_ptr); 




    PixelBuffer * buffer = new PixelBuffer(width, height, 
              ColorData(1, 1, static_cast<float>(0.95))); 

    //png_bytep * row_pointer[width * 4]; 

    png_bytep * row_pointers = new png_bytep[height](); 

    for (int y=0; y<height; y++){ 
     std::cout << png_get_rowbytes(png_ptr,info_ptr) << std::endl; 

     row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); 
    } 


    png_read_image(png_ptr, row_pointers); 

    std::cout << row_pointers << std::endl; 

    for (int x=0; x<width;x++){ 
     for (int y=0; y < height; y++){ 
      int height_iterator = height - 1; 
      int r = row_pointers[y][x*4]; 
      int g = row_pointers[y][x*4+1]; 
      int b = row_pointers[y][x*4+2]; 
      int a = row_pointers[y][x*4+3]; 
      if (a == 255) 
       printf("R: %d G: %d B: %d A: %d\n", r, g, b, a); 
      buffer->set_pixel(x, height_iterator - y, ColorData(r/255, 
                   g/255, b/255, 
               a/255)); 
     } 
    } 
    return buffer; 
} 

J'ai essayé d'inverser l'octet de remplissage à 0x0 et j'ai toujours une image noire. L'instruction printf à l'intérieur de la boucle semble être une couleur valide, et je n'arrive pas à comprendre pourquoi elle ne fonctionne pas.

Comment puis-je obtenir l'image pour charger autre chose qu'une image noire?

Répondre

1

Je suppose que ColorData accepte les flottants dans l'intervalle [0, 1]. Modifiez l'appel au constructeur ColorData à ColorData(r/255.0f, g/255.0f, b/255.0f, a/255.0f) pour obtenir des valeurs à virgule flottante au lieu de zéros entiers.

+0

C'était tout! Je devais avoir de la chance avec mon autre image étant exactement 255 ou 0 –