tagBITMAPINFO
时间: 2024-02-15 22:05:44 浏览: 11
`tagBITMAPINFO` 是一个结构体类型,定义在 Windows.h 头文件中。该结构体描述了一个位图的信息,包括位图的宽度、高度、水平和垂直分辨率、颜色位数等。
该结构体的定义如下:
```
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
```
其中,`BITMAPINFOHEADER` 是一个结构体类型,用于描述位图的头部信息,包括位图的宽度、高度、颜色平面数、颜色位数等。而 `RGBQUAD` 则是一个结构体类型,用于描述位图的调色板信息,包括红、绿、蓝三个分量的颜色值。
`tagBITMAPINFO` 结构体将这两个信息组合在一起,它包含一个 `bmiHeader` 成员和一个 `bmiColors` 成员。其中,`bmiHeader` 成员是一个 `BITMAPINFOHEADER` 类型的结构体,用于描述位图的头部信息;而 `bmiColors` 成员则是一个 `RGBQUAD` 类型的数组,用于描述位图的调色板信息。由于数组长度只有 1,因此该结构体实际上只包含一个调色板项。
在 Windows API 中,该结构体常用于位图的创建、加载和保存等操作,以便程序能够正确地处理位图的信息和数据。
相关问题
bmp单色位图抗锯齿算法MFC代码实现
以下是一个简单的MFC程序实现bmp单色位图抗锯齿算法的代码示例:
1. 定义位图数据结构:
```
typedef struct tagBITMAPINFO_MONOCHROME {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[2];
} BITMAPINFO_MONOCHROME;
```
2. 载入位图文件:
```
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
```
3. 将位图数据转换为单色位图数据:
```
CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SelectObject(&bitmap);
BITMAP bmp;
bitmap.GetBitmap(&bmp);
BITMAPINFO_MONOCHROME bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bmp.bmWidth;
bmi.bmiHeader.biHeight = bmp.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = ((bmp.bmWidth + 31) / 32) * 4 * bmp.bmHeight;
bmi.bmiColors[0].rgbBlue = bmi.bmiColors[0].rgbGreen = bmi.bmiColors[0].rgbRed = 0;
bmi.bmiColors[1].rgbBlue = bmi.bmiColors[1].rgbGreen = bmi.bmiColors[1].rgbRed = 255;
BYTE* pBits = NULL;
HBITMAP hBitmap = CreateDIBSection(dc.GetSafeHdc(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
dc.SelectObject(hBitmap);
::GetDIBits(dc.GetSafeHdc(), (HBITMAP)bitmap, 0, bmp.bmHeight, pBits, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
```
4. 对单色位图进行抗锯齿处理:
```
for (int y = 0; y < bmi.bmiHeader.biHeight; y++) {
for (int x = 0; x < bmi.bmiHeader.biWidth; x++) {
int index = y * ((bmi.bmiHeader.biWidth + 31) / 32) + x / 32;
int bit = 1 << (31 - x % 32);
if (pBits[index] & bit) {
if ((x > 0 && !(pBits[index] & (bit >> 1))) ||
(x < bmi.bmiHeader.biWidth - 1 && !(pBits[index] & (bit << 1))) ||
(y > 0 && !(pBits[index - ((bmi.bmiHeader.biWidth + 31) / 32)] & bit)) ||
(y < bmi.bmiHeader.biHeight - 1 && !(pBits[index + ((bmi.bmiHeader.biWidth + 31) / 32)] & bit))) {
pBits[index] &= ~bit;
}
}
}
}
```
5. 绘制抗锯齿处理后的单色位图:
```
CClientDC dc(this);
dc.StretchBlt(0, 0, bmp.bmWidth, bmp.bmHeight, CDC::FromHandle(dcMemory), 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
```
完整的MFC程序代码示例:
```
typedef struct tagBITMAPINFO_MONOCHROME {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[2];
} BITMAPINFO_MONOCHROME;
void AntiAliasingMonochromeBitmap(CDC* pDC, HBITMAP hBitmap, int cx, int cy)
{
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);
dcMemory.SelectObject(hBitmap);
BITMAP bmp;
::GetObject(hBitmap, sizeof(BITMAP), &bmp);
BITMAPINFO_MONOCHROME bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bmp.bmWidth;
bmi.bmiHeader.biHeight = bmp.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 1;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = ((bmp.bmWidth + 31) / 32) * 4 * bmp.bmHeight;
bmi.bmiColors[0].rgbBlue = bmi.bmiColors[0].rgbGreen = bmi.bmiColors[0].rgbRed = 0;
bmi.bmiColors[1].rgbBlue = bmi.bmiColors[1].rgbGreen = bmi.bmiColors[1].rgbRed = 255;
BYTE* pBits = NULL;
HBITMAP hBitmapMono = CreateDIBSection(dcMemory.GetSafeHdc(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
dcMemory.SelectObject(hBitmapMono);
::GetDIBits(dcMemory.GetSafeHdc(), hBitmap, 0, bmp.bmHeight, pBits, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
for (int y = 0; y < bmi.bmiHeader.biHeight; y++) {
for (int x = 0; x < bmi.bmiHeader.biWidth; x++) {
int index = y * ((bmi.bmiHeader.biWidth + 31) / 32) + x / 32;
int bit = 1 << (31 - x % 32);
if (pBits[index] & bit) {
if ((x > 0 && !(pBits[index] & (bit >> 1))) ||
(x < bmi.bmiHeader.biWidth - 1 && !(pBits[index] & (bit << 1))) ||
(y > 0 && !(pBits[index - ((bmi.bmiHeader.biWidth + 31) / 32)] & bit)) ||
(y < bmi.bmiHeader.biHeight - 1 && !(pBits[index + ((bmi.bmiHeader.biWidth + 31) / 32)] & bit))) {
pBits[index] &= ~bit;
}
}
}
}
pDC->StretchBlt(0, 0, cx, cy, &dcMemory, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
}
void CTestDlg::OnPaint()
{
CPaintDC dc(this);
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
AntiAliasingMonochromeBitmap(&dc, (HBITMAP)bitmap, 200, 200);
}
```
用MFC写一段由无压缩形式的bmp格式图片生成压缩格式为BI_RLE8的代码
以下是使用MFC库生成BI_RLE8压缩格式的bmp图片的示例代码:
```cpp
// 定义BITMAPFILEHEADER结构体
typedef struct tagBITMAPFILEHEADER {
WORD bfType; // 位图文件的类型,必须为"BM"格式
DWORD bfSize; // 位图文件的大小,以字节为单位
WORD bfReserved1; // 保留,必须为0
WORD bfReserved2; // 保留,必须为0
DWORD bfOffBits; // 从文件头到位图数据的偏移量,以字节为单位
} BITMAPFILEHEADER;
// 定义BITMAPINFO结构体
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位图信息头
RGBQUAD bmiColors[1]; // 调色板,只有8位图像才有
} BITMAPINFO;
// 生成压缩格式为BI_RLE8的bmp图片
void GenerateRLE8Bmp(const CString& bmpFileName, int bmpWidth, int bmpHeight, const BYTE* bmpData) {
// 打开文件
CFile bmpFile(bmpFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);
// 定义文件头
BITMAPFILEHEADER bmpFileHeader;
bmpFileHeader.bfType = 0x4D42; // 位图文件类型
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD) + bmpWidth * bmpHeight; // 文件大小
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); // 位图数据偏移量
// 写入文件头
bmpFile.Write(&bmpFileHeader, sizeof(BITMAPFILEHEADER));
// 定义位图信息头
BITMAPINFOHEADER bmpInfoHeader;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER); // 位图信息头大小
bmpInfoHeader.biWidth = bmpWidth; // 位图宽度
bmpInfoHeader.biHeight = bmpHeight; // 位图高度
bmpInfoHeader.biPlanes = 1; // 位图颜色平面数,必须为1
bmpInfoHeader.biBitCount = 8; // 每个像素的位数,必须为8
bmpInfoHeader.biCompression = BI_RLE8; // 压缩类型,必须为BI_RLE8
bmpInfoHeader.biSizeImage = bmpWidth * bmpHeight; // 位图数据大小,以字节为单位
bmpInfoHeader.biXPelsPerMeter = 0; // 水平分辨率,以像素每米为单位
bmpInfoHeader.biYPelsPerMeter = 0; // 垂直分辨率,以像素每米为单位
bmpInfoHeader.biClrUsed = 256; // 颜色表中实际使用的颜色数
bmpInfoHeader.biClrImportant = 0; // 对图像显示有重要影响的颜色数
// 写入位图信息头
bmpFile.Write(&bmpInfoHeader, sizeof(BITMAPINFOHEADER));
// 定义调色板
RGBQUAD bmpColors[256];
for (int i = 0; i < 256; i++) {
bmpColors[i].rgbBlue = i;
bmpColors[i].rgbGreen = i;
bmpColors[i].rgbRed = i;
bmpColors[i].rgbReserved = 0;
}
// 写入调色板
bmpFile.Write(bmpColors, 256 * sizeof(RGBQUAD));
// 定义压缩后的位图数据
BYTE* rle8Data = new BYTE[bmpWidth * bmpHeight];
BYTE* rle8Ptr = rle8Data;
for (int i = 0; i < bmpHeight; i++) {
BYTE* rowPtr = (BYTE*)bmpData + (bmpHeight - i - 1) * bmpWidth;
int rowSize = bmpWidth;
while (rowSize > 0) {
int count = 1;
BYTE color = *rowPtr;
rowPtr++;
rowSize--;
while (rowSize > 0 && count < 255 && *rowPtr == color) {
count++;
rowPtr++;
rowSize--;
}
*rle8Ptr++ = count;
*rle8Ptr++ = color;
}
*rle8Ptr++ = 0;
*rle8Ptr++ = 0;
}
// 写入位图数据
bmpFile.Write(rle8Data, bmpWidth * bmpHeight);
// 关闭文件
bmpFile.Close();
// 释放内存
delete[] rle8Data;
}
```
调用示例:
```cpp
// 定义位图数据
const int bmpWidth = 320;
const int bmpHeight = 240;
BYTE bmpData[bmpWidth * bmpHeight];
memset(bmpData, 0, bmpWidth * bmpHeight);
for (int i = 0; i < bmpWidth * bmpHeight; i++) {
bmpData[i] = rand() % 256;
}
// 生成压缩格式为BI_RLE8的bmp图片
GenerateRLE8Bmp(_T("test.bmp"), bmpWidth, bmpHeight, bmpData);
```