加载RGB PNG会产生黑色图像

时间:2016-11-15 14:05:16

标签: c++ libpng

我正在使用libpng库将png文件加载到PixelBuffer,这只是一个二维数组或RGBA值。

以下代码适用于包含Alpha通道的图像,但不适用于不包含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;
}

我尝试将填充字节翻转到0x0,但仍然会产生黑色图像。

循环中的printf语句看起来像有效的颜色,我似乎无法弄清楚它为什么不起作用。

如何让图像加载黑色图像以外的其他内容?

1 个答案:

答案 0 :(得分:1)

我假设ColorData接受[0,1]范围内的浮点数。将对ColorData构造函数的调用更改为ColorData(r/255.0f, g/255.0f, b/255.0f, a/255.0f),以便获得浮点值而不是整数零。