一个关于位图(BMP)的问题!

yyfzy 2006-06-01 02:36:34
最近我在写一个图片库,首先要支持的当然是最简单的位图格式图片,但是还是出现了不明白的地方。

我现在是用下面的代码来加载bmp文件,并使用GDI绘制出来,效果没有任何问题。

//Open file
ifstream inf(pszFile, ios::binary);
if(0 == inf.is_open())
return false;

//Load the file header
BITMAPFILEHEADER header;
memset(&header, 0, sizeof(header));
inf.read((char*)&header, sizeof(header));
if(header.bfType != 0x4D42)
return false;

//Load the image information header
BITMAPINFOHEADER infoheader;
memset(&infoheader, 0, sizeof(infoheader));
inf.read((char*)&infoheader, sizeof(infoheader));
m_iImageWidth = infoheader.biWidth;
m_iImageHeight = infoheader.biHeight;
m_iBitsPerPixel = infoheader.biBitCount;

//Calculate the image data size
int iLineByteCnt = (((m_iImageWidth*m_iBitsPerPixel) + 31) >> 5) << 2;
m_iImageDataSize = iLineByteCnt * m_iImageHeight;

//Load the image data to buffer
if(m_pImageData) delete []m_pImageData;
m_pImageData = new unsigned char[m_iImageDataSize];
inf.read((char*)m_pImageData, m_iImageDataSize);

inf.close();

但是内存里(也就是指针pImageData )的数据不是RGB格式,而是BGR格式!然后我用UltraEdit打开bmp文件,发现在文图文件里的确是BGR格式。

位图文件里的图片数据不应该是RGB格式吗?怎么成了BGR?
既然是BGR各式的数据,我是用
StretchDIBits(hdc, iLeft, iTop, iWidth, iHeight,
0, 0, m_iImageWidth, m_iImageHeight,
m_pImageData, &bmi, DIB_RGB_COLORS, SRCCOPY);
绘制出来的图像怎么没有错误呢?R与B的效果没有互换?

同时我在写Tga图片的解码,Tga图片格式的确是BGR,也就是说加载后要进行BGR->RGB的转化后再使用GDI绘制才能看到正确的效果,奇怪的时候也不需要这个转化,把BGR各式的数据送给GDI就可以看到正确的效果,为什么?

希望有人指点迷津!
...全文
495 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tian_Dao_Akane 2006-06-02
  • 打赏
  • 举报
回复
学习了。
yinzhaohui 2006-06-02
  • 打赏
  • 举报
回复
直接看看BMP格式文栏什么都知道了(这些都是有标准的不是你我说了算)http://www.wotsit.org/
Kudeet 2006-06-01
  • 打赏
  • 举报
回复
1,我以前在OpenGL里,tga图片都要转化后才能得到正确的效果,否则R和B的效果互换了。
=====
这个只代表OPENGL,上面也讲了你看看RGBQUAD的顺序就明白了.OPENGL和GDI/DX不同
2,使用GDI的时候,要求的也是RGB格式的图片数据,所以我按照以前的经验认为需要转化
======
我讲过,这里的RGB只是一个名字.并没有哪里规定你一定要提高RGB顺序的数据,相反,根据RGBQUAD的顺序,数据应该是BGR的. 记住了,RGB只是代表一种三色的加色颜色空间,顺序你想怎么读就怎么读.
soaroc 2006-06-01
  • 打赏
  • 举报
回复
正好在学OpenGL,其中的存储格式是可以自己设置的,使用函数glPixelStore就可以设置任何的格式了。
zxyjyzxyjy 2006-06-01
  • 打赏
  • 举报
回复
看看这两个结构就知道位图中的数据是如何何存的了
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;

typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
dch4890164 2006-06-01
  • 打赏
  • 举报
回复
学习了!!
帮顶
关注!!
yyfzy 2006-06-01
  • 打赏
  • 举报
回复
To:laiyiling(提问前可在[search.csdn.net/lt/]搜索答案)

1,我以前在OpenGL里,tga图片都要转化后才能得到正确的效果,否则R和B的效果互换了。
2,使用GDI的时候,要求的也是RGB格式的图片数据,所以我按照以前的经验认为需要转化。
yyfzy 2006-06-01
  • 打赏
  • 举报
回复
也就是说,在windows里,或者说是在ms规定的地方,说的是RGB,但是存储的时候是BGR?

那如果是32位的颜色呢,也就是RGBA格式,存储的时候是BGRA还是ARGB?

是不是ms吧RGBA当这一个双字的数据一次写入的?那RGB的时候又怎么解释?

Kudeet 2006-06-01
  • 打赏
  • 举报
回复
RGB你可以认为只是我们经常这样读而已,实际存储是BGR, Tga图片格式的确是BGR, 不知道你为什么认为要转换才能正确显示?
lixiaosan 2006-06-01
  • 打赏
  • 举报
回复
opengl标准不是ms弄的吧。。。
thisisll 2006-06-01
  • 打赏
  • 举报
回复
BMP本身就是这么反着存的
thisisll 2006-06-01
  • 打赏
  • 举报
回复
还是让三抢先了~~~
yyfzy 2006-06-01
  • 打赏
  • 举报
回复
但是我在做3D(OpenGL)的时候,数据的顺序和格式是一一对应的,也就是说如果image data是
0 0 255,format = GL_RGB 时是蓝色,format = GL_BGR_EXT 时是红色。

是不是OpenGL和GDI里处理不一样?
lixiaosan 2006-06-01
  • 打赏
  • 举报
回复
ms就是要nb些, 在windows中,rgb就是反着存的,表现为bgr

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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