首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

windows显示64位位图有关问题(libpng)

2013-06-25 
windows显示64位位图问题(libpng)本帖最后由 vegapan 于 2013-04-19 09:28:07 编辑首先,一直以为位图里面

windows显示64位位图问题(libpng)
本帖最后由 vegapan 于 2013-04-19 09:28:07 编辑 首先,一直以为位图里面每个颜色分量取值范围是0-255,
现在遇到了64位图片,每个分量为0-65535。
问题是同一个颜色在两种表示方式中如何转换?

这是我自己写的一个小工具,用libpng读取图片之后,显示到窗口。
读取32位png没有问题,如果是64位的就遇到以上问题。我的解决方式遇到的问题是
图片中会出现很多噪点,就是在颜色分界处会出现很多斑点。

HBITMAP png_convert_bmp(image_data* img_data, int row, int col, int height, int width){
if (img_data == NULL){
return NULL;
}

png_structp png_ptr = img_data->png_ptr;
png_infop info_ptr = img_data->info_ptr;

png_bytep* row_ptr = png_get_rows(png_ptr, info_ptr);

// Read into CBitmap
int bit_depth =  png_get_bit_depth(png_ptr, info_ptr);
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
int step = get_step(color_type);

if (width == 0 && height == 0){
width = png_get_image_width(png_ptr, info_ptr);
height = png_get_image_height(png_ptr, info_ptr);
}
int _rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    // int _rb = png_get_rowbytes(png_ptr, info_ptr);

/////
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));

BITMAPINFOHEADER& bih = bmi.bmiHeader;
bih.biSize = sizeof(bih);
bih.biWidth = width;
bih.biHeight = -height;
    bih.biPlanes = 1;
    bih.biBitCount = 32;
    bih.biCompression = BI_RGB;

 

// Create the DIB section with an alpha channel.
BYTE* lpBits = NULL;
HBITMAP hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&lpBits, 0, 0);
    // free(bmi); bmi = NULL;
     
img_data->x = img_data->y = 10000;
img_data->r = img_data->b = 0; 

//int C = 0;
for (int i = 0; i < height; i++){
unsigned char* tar = (unsigned char*)(lpBits + i * _rowbytes / 2);
        if (bit_depth == 16){
            for (int j = 0; j < width; j++){
    int col_offset = col * 4 + j * 4;
                unsigned short* src = (unsigned short*)row_ptr[i + row];
    unsigned int r = src[col_offset + 0];
    unsigned int g = src[col_offset + 1];
    unsigned int b = src[col_offset + 2];
    unsigned int a = src[col_offset + 3];
                
    tar[j * 4 + 3] = (BYTE)(a >> 8);
    tar[j * 4 + 2] = (BYTE)((r * a) >> 16); //Blue


    tar[j * 4 + 1] = (BYTE)((g * a) >> 16); //Green
    tar[j * 4 + 0] = (BYTE)((b * a) >> 16); //Red                
                

    int _x = j;
    if (a > 0){
    // Parse the boundary
    if (img_data->y > i){
    img_data->y = i;
    }
    else if (img_data->b < i){
    img_data->b = i;
    }
    if (img_data->x > _x){
    img_data->x = _x;
    }
    else if (img_data->r < _x){
    img_data->r = _x;
    }
    }
    }
        }
        else{
            int tar_offset = _rowbytes * i;
    for (int j = 0; j < width; j++){
                int src_offset = step * (j + col);
    int r = row_ptr[i + row][src_offset + 0];
    int g = row_ptr[i + row][src_offset + 1];
    int b = row_ptr[i + row][src_offset + 2];
    int a = row_ptr[i + row][src_offset + 3];
    ////RGBA -> BGRA Pre-Multipie
    lpBits[tar_offset + j * step + 3] = (BYTE)(a >> 8);
    lpBits[tar_offset + j * step + 2] = (BYTE)(r * a >> 16); //Blue
    lpBits[tar_offset + j * step + 1] = (BYTE)(g * a >> 16); //Green
    lpBits[tar_offset + j * step + 0] = (BYTE)(b * a >> 16); //Red
                            // 至此为止功能结束,下面代码与显示没有直接关系。
    int _x = j;
    if (a > 0){
    // Parse the boundary
    if (img_data->y > i){
    img_data->y = i;
    }
    else if (img_data->b < i){
    img_data->b = i;
    }
    if (img_data->x > _x){
    img_data->x = _x;
    }


    else if (img_data->r < _x){
    img_data->r = _x;
    }
    }
    }
        }
}

// defer
// png_destroy_read_struct(&png_ptr, &info_ptr, 0);
return hBitmap;
} Windows Bitmap libpng
[解决办法]
0~65535/256 → 0..255

热点排行