64,642
社区成员
发帖
与我相关
我的任务
分享
if(bmpInfHeader.biBitCount == 24)
{
RGBTRIPLE* pRGB3;
pRGB3 = new RGBTRIPLE[bmpInfHeader.biWidth * bmpInfHeader.biHeight];
BYTE addtion = (bmpInfHeader.biWidth*3) % 4;
addtion = 4 - addtion;
for(int k=0; k<bmpInfHeader.biHeight; k++)
{
if(openFile.Read(&pRGB3[k * bmpInfHeader.biWidth], bmpInfHeader.biWidth * 3) < bmpInfHeader.biWidth * 3)
{
MessageBox(L"ERROR");
return;
}
openFile.Seek(addtion, CFile::current);
}
// openFile.Read(pRGB3, bmpInfHeader.biWidth * bmpInfHeader.biHeight * 3);
for(int i=0; i< bmpInfHeader.biHeight; i++)
{
for(int j =0; j< bmpInfHeader.biWidth; j++)
{
pDC->SetPixelV(j, bmpInfHeader.biHeight - i, RGB(pRGB3[i*bmpInfHeader.biWidth+j].rgbtRed,pRGB3[i*bmpInfHeader.biWidth+j].rgbtGreen,pRGB3[i*bmpInfHeader.biWidth+j].rgbtBlue));
}
}
delete [] pRGB3;
}
看了一本数字图像处理的书,上面说到BMP位图的每行都必须是4字节的整数倍,不足的用0补充。这一点对32位色的位图没影响,对于少于32色的图像有影响
但是书上还说道像素数组的排列方式有正向和负向之分,不怎么理解,有人知道的请帮忙说明一下
void CBMPView::OnFileOpen()
{
// TODO: 在此添加命令处理程序代码
CFileDialog fileDlg(TRUE);
//注意过滤器组的写法
//1. 每一组过滤器由一对字符串构成(每个字符串以\0结尾),第一个字符串是类型说明,
// 第二个字符串则是过滤格式,如果一组过滤器对多种格式过滤,不同的格式间用分号隔开
// 每一种格式由*.加上拓展名构成。
//2. 如果有多组过滤,那么有几组过滤就有几组字符串。
//3. 实例
// fileDlg.m_ofn.lpstrFilter =L"位图文件(*.bmp),文本文件(*.txt)\0*.bmp;*.txt\0音频文件(.mp3)\0*.mp3\0";
fileDlg.m_ofn.lpstrFilter =L"位图文件\0*.bmp\0";
if(IDOK == fileDlg.DoModal())
{
//打开BMP文件
CFile openFile(fileDlg.m_ofn.lpstrFile, CFile::modeRead | CFile::typeBinary);
//获取位图文件头、信息头
BITMAPFILEHEADER bmpFileHeader;
openFile.Read(&bmpFileHeader, 14);
BITMAPINFOHEADER bmpInfHeader;
openFile.Read(&bmpInfHeader, 40);
//绘制视图
CDC* pDC = GetDC();
openFile.Seek(bmpFileHeader.bfOffBits, CFile::begin);
if(bmpInfHeader.biBitCount == 24)
{
RGBTRIPLE* pRGB3;
pRGB3 = new RGBTRIPLE[bmpInfHeader.biWidth * bmpInfHeader.biHeight];
openFile.Read(pRGB3, bmpInfHeader.biWidth * bmpInfHeader.biHeight * 3);
for(int i=0; i< bmpInfHeader.biHeight; i++)
{
for(int j =0; j< bmpInfHeader.biWidth; j++)
{
pDC->SetPixelV(j, bmpInfHeader.biHeight - i, RGB(pRGB3[i*bmpInfHeader.biWidth+j].rgbtRed,pRGB3[i*bmpInfHeader.biWidth+j].rgbtGreen,pRGB3[i*bmpInfHeader.biWidth+j].rgbtBlue));
}//这里纵坐标如果直接用i图像显示出来是倒置的
}
delete [] pRGB3;
}
else if(bmpInfHeader.biBitCount == 32)
{
RGBQUAD* pRGB4;
pRGB4 = new RGBQUAD[bmpInfHeader.biWidth * bmpInfHeader.biHeight];
openFile.Read(pRGB4, bmpInfHeader.biWidth * bmpInfHeader.biHeight * 4);
for(int i=0; i< bmpInfHeader.biHeight; i++)
{
for(int j =0; j< bmpInfHeader.biWidth; j++)
{
pDC->SetPixelV(j, bmpInfHeader.biHeight - i, RGB(pRGB4[i*bmpInfHeader.biWidth+j].rgbRed,pRGB4[i*bmpInfHeader.biWidth+j].rgbGreen,pRGB4[i*bmpInfHeader.biWidth+j].rgbBlue));
}
}
delete [] pRGB4;
}
else
{
MessageBox(L"不支持的位图格式");
}
openFile.Close();
ReleaseDC(pDC);
}
}
CDC* pDC = GetDC();
BITMAPINFO* pbi = (BITMAPINFO*)new BYTE[40];//没有调色板,仅用于真彩色
//关于 BITMAPINFO 对象的构造涉及到一个长度为1的颜色结构的数组,其意义参见
//http://blog.csdn.net/zhanyan4s/article/details/8718499
pbi->bmiHeader = bmpInfHeader;
BYTE* buffer = NULL;
ULONG len =0;
if(bmpInfHeader.biBitCount == 24)
{
BYTE addtion = (bmpInfHeader.biWidth*3) % 4;
if(addtion)
{
addtion = 4 - addtion;
len = (bmpInfHeader.biWidth * 3 + addtion) * bmpInfHeader.biHeight;
}
else
{
len = bmpInfHeader.biWidth * bmpInfHeader.biHeight * 3;
}
}
else if(bmpInfHeader.biBitCount == 32)
{
len = bmpInfHeader.biWidth * bmpInfHeader.biHeight * 4;
}
else
{
MessageBox(L"不支持的位图格式");
openFile.Close();
ReleaseDC(pDC);
return;
}
buffer = new BYTE[len];
openFile.Seek(bmpFileHeader.bfOffBits, CFile::begin);
if(openFile.Read(buffer, len) < len)
{
MessageBox(L"ERROR");
delete [] buffer;
openFile.Close();
ReleaseDC(pDC);
return;
}
::SetDIBitsToDevice(pDC->m_hDC, 0, 0, bmpInfHeader.biWidth, bmpInfHeader.biHeight, 0, 0, 0, bmpInfHeader.biHeight, buffer, pbi, DIB_RGB_COLORS);
openFile.Close();
ReleaseDC(pDC);
DIB有关的AIP函数有
SetDIBitsToDevice
SetDIBits
StretchDIBits
GetDIBits
GetDIBColorTable
MFC中的CBitmap可以用来处理BMP位图
从第一种处理BMP位图的方式可以看出BMP格式的位图没有进行数据压缩