BITMAPINFOHEADER.biCompression是BI_BITFIELDS的BMP怎么解码?

tongchi 2002-09-11 08:31:13
biCompression是BI_BITFIELDS时,按MSDN上的说法这个标识用在16位和32位的BMP上,有三个DWORD作为图片数据的MASK,我试着忽略这个东东,解出来的图片色彩实在是惨不忍睹,不知道谁告诉我有这个标志的bmp该怎么解?
...全文
1600 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wqyuwss 2002-09-13
  • 打赏
  • 举报
回复
这是指的图像用行城编码压缩
tongchi 2002-09-13
  • 打赏
  • 举报
回复
谢谢你的提醒,我已经搞定了,另外搜来的资料,也许你也有兴趣:

biBitCount=16 表示位图最多有216种颜色。每个色素用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系统中,则没有格式限制,只不过要求掩码之间不能有重叠。(注:这种格式的图像使用起来是比较麻烦的,不过因为它的显示效果接近于真彩,而图像数据又比真彩图像小的多,所以,它更多的被用于游戏软件)。

有机会多交流!
SkyWalkerJ 2002-09-12
  • 打赏
  • 举报
回复
这个,说老实话我并没有做过,但知道有那么回事,使用上应该和局域网里所用的子网掩码是一样的,Blue掩码是1的位,就是代表Blue的。三个掩码应该是放在BITMAPINFOHEADER后面的颜色表里,你可以查查MSDN。
tongchi 2002-09-12
  • 打赏
  • 举报
回复
SkyWalkerJ兄,我现在需要解这种格式的BMP,能不能具体讲一下这三个掩码是怎样指定的16位的图像数据的位分布?在32位中又是怎样的呢?谢了。
SkyWalkerJ 2002-09-12
  • 打赏
  • 举报
回复
大哥,怎么能忽略呢,这三个掩码指定了RGB三种颜色的位结构啊,就是在一个像素的16个bit中,哪几位是R,哪几位是G,哪几位是B,你忽略了它们,还怎么解码??
void CExample10View::OnSave555BiBitfields() { // TODO: Add your command handler code here if(lpBmpDataBuf==NULL) { MessageBox("当前没有打开的位图"); return; } BYTE r,g,b; LPBYTE lpDest,lpSrc; int i,j; int nheapSize; CFileDialog filesavebox(FALSE,"bmp","BI_BITFIELDS.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,"files(*.bmp)|*.bmp|",NULL); CFile file; CString strPathname; if(m_bmi.biBitCount!=24) { MessageBox("当前打开的位图不是24位位图"); return; } memcpy(&m_newbmf,&m_bmf,sizeof(BITMAPFILEHEADER)); memcpy(&m_newbmi,&m_bmi,sizeof(BITMAPINFOHEADER)); m_newbmi.biBitCount=16; m_newbmi.biCompression=BI_BITFIELDS;//即3 m_newbmi.biSizeImage=WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; m_newbmf.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; m_newbmf.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3; nheapSize=sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*m_newbmi.biHeight; if(lpnewBmpDataBuf!=NULL) { delete []lpnewBmpDataBuf; lpnewBmpDataBuf=NULL; } lpnewBmpDataBuf=new BYTE[nheapSize]; memcpy(lpnewBmpDataBuf,&m_newbmi,sizeof(BITMAPINFOHEADER)); DWORD* lp=(DWORD*)(lpnewBmpDataBuf+sizeof(BITMAPINFOHEADER)); *lp++=0x00007c00; *lp++=0x000003e0; *lp =0x0000001f; for(i=0;ibiHeight;i++) { for(j=0;jbiWidth;j++) { lpSrc=lpBmpDataBuf+sizeof(BITMAPINFOHEADER) +WIDTHBYTES(m_bmi.biWidth,m_bmi.biBitCount)*(m_bmi.biHeight-1-i) +j*3; lpDest=lpnewBmpDataBuf+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3 +WIDTHBYTES(m_newbmi.biWidth,m_newbmi.biBitCount)*(m_newbmi.biHeight-1-i) +j*2; b=*lpSrc++; b&=0xf8; g=*lpSrc++; g&=0xf8; r=*lpSrc++; r&=0xf8; WORD* lp=(WORD*)lpDest; *lp=0; *lp=r<<7; *lp+=(g<>3); } } if(filesavebox.DoModal()!=IDOK) return; strPath

8,307

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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