2016-11-15 1 views
0

Ich benutze die libpng-Bibliothek, um png-Dateien in einen PixelBuffer zu laden, der einfach ein 2D-Array oder RGBA-Werte ist.Laden von RGB-PNG-Ergebnissen in schwarzes Bild

Der folgende Code funktioniert für und Bild, das einen Alphakanal enthält, aber nicht auf einem Bild, das den Alphakanal nicht enthält.

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; 
} 

Ich habe versucht, den Füller Byte auf 0x0 Spiegeln und in einem schwarzen Bild führen nach wie vor.

Die printf-Anweisung innerhalb der Schleife scheint wie gültige Farben, und ich kann nicht herausfinden, warum es nicht funktioniert.

Wie kann ich das Bild laden, etwas anderes als ein schwarzes Bild zu laden?

Antwort

1

Ich nehme an, ColorData akzeptiert Floats im Bereich [0, 1]. Ändern Sie den Aufruf des ColorData-Konstruktors in ColorData(r/255.0f, g/255.0f, b/255.0f, a/255.0f), sodass Sie Fließkommawerte anstelle von ganzzahligen Nullen erhalten.

+0

Das war es! Ich muss mit meinem anderen Bild Glück gehabt haben, das genau 255 oder 0 ist –

Verwandte Themen