如何提取16bit bmp rgb颜色值

tangsave 2010-08-09 05:28:45
FILE *fp=fopen(bmpName,"rb");
if(fp==0) return 0;
//跳过位图文件头结构BITMAPFILEHEADER
fseek(fp, sizeof(BITMAPFILEHEADER),0);
定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);
//获取图像宽、高、每像素所占位数等信息
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
biBitCount = head.biBitCount;
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
//灰度图像有颜色表,且颜色表表项为256
//申请位图数据所需要的空间,读位图数据进内存
pBmpBuf=new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf,1,lineByte * bmpHeight,fp);
//关闭文件
fclose(fp);

int i,j;

//每行字节数
int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
int r,g,b;
for(i=0;i<bmpHeight;i++)
{
for(j=0;j<bmpWidth;j++)
{
r=*(pBmpBuf+i*lineByte+j*2);
g=*(pBmpBuf+i*lineByte+j*2+1);
b=*(pBmpBuf+i*lineByte+j*2+2);
}

}

取得的RGB有色差,是什么地方不对。
查BMP文件格式的资料,说16bit图片要设置颜色索引表,但有此资料又说不用,说每5位表示一个rgb分量。
又不是太明白转换原理。

求指点~~~~~
...全文
560 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
tangsave 2010-08-10
  • 打赏
  • 举报
回复
hastings方法可行,生成的图片没有偏色。

biCompression字段值是BI_BITFIELDS要设三个32位颜色屏蔽值

但是我生成的图片是没压缩的,说明16bit的都要加这个32屏蔽值.
bih.biCompression= BI_RGB;//未压缩格式

搞定,谢谢了,结帖给分罗~~~~~~~~~
senlinzhiwang 2010-08-09
  • 打赏
  • 举报
回复
学习了!!!
dirdirdir3 2010-08-09
  • 打赏
  • 举报
回复
要看是什么格式的,16bit的有多种格式........
16位位图表示位图最多有2^16种颜色。每个色素用16位(2个字节)表示。这种格式叫作高彩色,或叫增强型16位色,或64K色。它的情况比较复杂,当biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,最高的一位保留,设为0。这种格式也被称作555 16位位图。如果biCompression成员的值是BI_BITFIELDS,那么情况就复杂了,首先是原来调色板的位置被三个DWORD变量占据,称为红、绿、蓝掩码。分别用于描述红、绿、蓝分量在16位中所占的位置。在Windows 95(或98)中,系统可接受两种格式的位域:555和565,在555格式下,红、绿、蓝的掩码分别是:0x7C00、0x03E0、0x001F,而在565格式下,它们则分别为:0xF800、0x07E0、0x001F。你在读取一个像素之后,可以分别用掩码“与”上像素值,从而提取出想要的颜色分量(当然还要再经过适当的左右移操作)。在NT系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。
hastings 2010-08-09
  • 打赏
  • 举报
回复
如果是16位的BITMAPINFOHEADER类型的位图,
你需要检查BITMAPINFOHEADER结构的biCompression字段,
如果它的值是BI_BITFIELDS,则紧跟BITMAPINFOHEADER结构的后面是三个DWORD的值:
是三个32位颜色屏蔽值,第一个用于红色,第二个用于绿色,第三个用于蓝色。
(16位一般都是没的,32位有的可能性比较大)。
假设你是没的话,颜色值可以这样算:
WORD wPixel;
for(i=0;i<bmpHeight;i++)
{
for(j=0;j<bmpWidth;j++)
{
wPixel=*(WORD*)(pBmpBuf+i*lineByte+j*2);
Red= ((0x7C00 & wPixel) >> 10) << 3 ;
Green=((0x03E0 & wPixel) >> 5 ) << 3 ;
Blue= ((0x001F & wPixel) >> 0 ) << 3 ;
}
}


19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧