MFC程序里面现在有一些像素点的灰度值数据(整型0-255),如何将这些数据写入一个位图文件中?
即是自己创建一个位图文件,自己写位图文件头,信息头,颜色表和位图数据,关键是怎么通过C++把已知的像素点灰度数据转换为位图数据并且写入位图文件中...
即是自己创建一个位图文件,自己写位图文件头,信息头,颜色表和位图数据,关键是怎么通过C++把已知的像素点灰度数据转换为位图数据并且写入位图文件中
展开
1个回答
展开全部
在<Windows.h>这个头文件中定义了Bmp文件头。
在baike.baidu.com中(BMP格式)详细解释了Bmp文件头的结构。
我在这里就再给你解释一下吧:
// bmp文件的文件结构是:
struct BMP
{
struct BITMAPFILEHEADER
{
WORD bfType; // 永远是"BM"
DWORD bfSize; // 整个bmp文件的大小
WORD bfReserved1; // 永远是0
WORD bfReserved2; // 永远是0
DWORD bfOffBits; // bmp文件头的大小,此值 = sizeof (BMP)(用这个可以计算出下面的调色板的大小)
}fileHeader;
struct BITMAPINFO
{
BITMAPINFOHEADER infomationHeader; // bitmap信息头
RGBQUAD bmiColors[1/*fileHeader.bfOffBits - sizeof ( infomationHeader )-sizeof ( fileHeader )*/]; // 长度可变的调色板
}bitmapInfomation;
char bits[1/*imageSize*/]; // 像素矩阵
};
一个struct BMP就是整个.bmp文件里所包含的内容。
所以,你只需要填充struct BMP,然后把它写入.bmp文件就可以了。
一般步骤可以分为三大步:
针对你的情况:
// 1:填充信息头
你说的像素点灰度数据,就是像素矩阵里的数据。如果你的灰度数据是0-255之间的,那就是占8位。按微软定义的Bmp文件的要求,8位位图必须使用调色板。你要做的只是按要求填充BITMAPFILEHEADER。然后填充BITMAPINFO里的BITMAPINFOHEADER,这个结构关键的是这个(其他都顾名思义,就不用说了吧):
infomationHeader.biBitCount = 8; // 8位位图
// 2:填充调色板
然后,因为是8位位图,调色板中应该包含2^8 = 256个RGBQUAD结构,分别对应索引为0~255的颜色值。
如果要成像好一些,例如PS等专业软件,一般调色板的调配会是不规则的,用一些算法算出来的。
不过我们就不用那么苛刻了。直接按顺序给他们分配相应的灰度颜色即可。这样也正好让调色板的索引对上你的图像的灰度值,便可以直接把你的灰度图像复制到像素矩阵里了:
for ( int i = 0; i < 255 ; i++ )
bmiColors[i].rgbBlue = bmiColorsGreen[i]. = bmiColorsRed[i]. = i;
// 3:复制像素矩阵,写入文件
我们把调色板做得比较特别,所以可以把你的灰度图,直接复制到像素矩阵里。
memcpy ( ... );
最后,写入文件就好了。
祝你学习愉快^_^
在baike.baidu.com中(BMP格式)详细解释了Bmp文件头的结构。
我在这里就再给你解释一下吧:
// bmp文件的文件结构是:
struct BMP
{
struct BITMAPFILEHEADER
{
WORD bfType; // 永远是"BM"
DWORD bfSize; // 整个bmp文件的大小
WORD bfReserved1; // 永远是0
WORD bfReserved2; // 永远是0
DWORD bfOffBits; // bmp文件头的大小,此值 = sizeof (BMP)(用这个可以计算出下面的调色板的大小)
}fileHeader;
struct BITMAPINFO
{
BITMAPINFOHEADER infomationHeader; // bitmap信息头
RGBQUAD bmiColors[1/*fileHeader.bfOffBits - sizeof ( infomationHeader )-sizeof ( fileHeader )*/]; // 长度可变的调色板
}bitmapInfomation;
char bits[1/*imageSize*/]; // 像素矩阵
};
一个struct BMP就是整个.bmp文件里所包含的内容。
所以,你只需要填充struct BMP,然后把它写入.bmp文件就可以了。
一般步骤可以分为三大步:
针对你的情况:
// 1:填充信息头
你说的像素点灰度数据,就是像素矩阵里的数据。如果你的灰度数据是0-255之间的,那就是占8位。按微软定义的Bmp文件的要求,8位位图必须使用调色板。你要做的只是按要求填充BITMAPFILEHEADER。然后填充BITMAPINFO里的BITMAPINFOHEADER,这个结构关键的是这个(其他都顾名思义,就不用说了吧):
infomationHeader.biBitCount = 8; // 8位位图
// 2:填充调色板
然后,因为是8位位图,调色板中应该包含2^8 = 256个RGBQUAD结构,分别对应索引为0~255的颜色值。
如果要成像好一些,例如PS等专业软件,一般调色板的调配会是不规则的,用一些算法算出来的。
不过我们就不用那么苛刻了。直接按顺序给他们分配相应的灰度颜色即可。这样也正好让调色板的索引对上你的图像的灰度值,便可以直接把你的灰度图像复制到像素矩阵里了:
for ( int i = 0; i < 255 ; i++ )
bmiColors[i].rgbBlue = bmiColorsGreen[i]. = bmiColorsRed[i]. = i;
// 3:复制像素矩阵,写入文件
我们把调色板做得比较特别,所以可以把你的灰度图,直接复制到像素矩阵里。
memcpy ( ... );
最后,写入文件就好了。
祝你学习愉快^_^
追问
请问你知道怎么把这幅DIB图像在MFC控件中显示么。我现在是显示出来了但是拖动窗口,位图就消失了。位图显示调用的是StretchDIBits这个函数
追答
这不属于这个问题了哈。
不过我还是帮你解答吧。
这个在网上就有很详细的解答。我一时半会也说不清楚哈。主要是重载On什么什么Scroll的一个函数完成的。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询