运行测试效果:
代码:
复制代码
void CMyView::OnReadBmp()
{//读取BMP文件并显示
CDC *pDC = GetDC();
CFileDialog dlg(TRUE);
if(dlg.DoModal()==IDOK)
{//选择要打开的BMP图片
strFilePath=dlg.GetPathName();
}
if(strFilePath=="")
{//取消
return;
}
FILE *fp=fopen(strFilePath,"r");
BITMAPFILEHEADER fileheader;
BITMAPINFO info;
fread(&fileheader,sizeof(fileheader),1,fp);
if(fileheader.bfType!=0x4D42)
{//不是BMP位图文件
pDC->TextOut(100,200,"无位图文件 请选择位图文件");
fclose(fp);
return ;
}
UCHAR *buffer = NULL;
//读位图头部
fread(&info.bmiHeader, sizeof(BITMAPINFOHEADER), 1, fp);
//位图宽度
long width=info.bmiHeader.biWidth;
this->width = width;
//位图高度
long height=info.bmiHeader.biHeight;
this->height = height;
DWORD size;
if (info.bmiHeader.biSizeImage != 0)
{//带颜色表
size = info.bmiHeader.biSizeImage;
}
else
{//不带颜色表的
size = info.bmiHeader.biHeight*info.bmiHeader.biWidth*3;
}
buffer = new UCHAR[size];//分配缓冲区
if (buffer == NULL)
{//分配内存失败
delete[] buffer;
return;
}
//忽略头部字节
fseek(fp,fileheader.bfOffBits,0);
fread(buffer,size,1,fp);
int i,j;
#pragma region 16 color
// 16色图的解析
if(info.bmiHeader.biBitCount==4)
{
int pitch;
if(width%8==0)
pitch=width;
else
pitch=width+8-width%8;
RGBQUAD quad[16];
fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*16,0);
fread(quad,sizeof(RGBQUAD)*16,1,fp);
if(height>0)
{//height>0 表示图片颠倒
for(i=0; i<height; i++)
{
for(j=0; j<width; j++)
{
int index;
if(j%2==0)
index = buffer[(i*pitch+j)/2]/16;
if(j%2==1)
index = buffer[(i*pitch+j)/2]%16;
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{//图片不颠倒
for(i=0; i<0-height; i++)
{
for(j=0; j<width; j++)
{
int index;
if(j%2==0)
index = buffer[(i*pitch+j)/2]/16;
if(j%2==1)
index = buffer[(i*pitch+j)/2]%16;
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
#pragma endregion 16 color
#pragma region 256 color
// 256色图的解析
if(info.bmiHeader.biBitCount==8)
{
int pitch;
if(width%4==0)
{
pitch=width;
}
else
{
pitch=width+4-width%4;
}
RGBQUAD quad[256];
fseek(fp,fileheader.bfOffBits-sizeof(RGBQUAD)*256,0);
fread(quad,sizeof(RGBQUAD)*256,1,fp);
if(height>0)
{//height>0 表示图片颠倒
for(int i=0;i<height;i++)
{
for(int j=0;j<width;j++)
{
int index=buffer[i*pitch+j];
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{
for(int i=0;i<0-height;i++)
{
for(int j=0;j<width;j++)
{
int index=buffer[i*pitch+j];
UCHAR r=quad[index].rgbRed;
UCHAR g=quad[index].rgbGreen;
UCHAR b=quad[index].rgbBlue;
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
#pragma endregion 256 color
#pragma region 24 bit
// 24位图解析
if(info.bmiHeader.biBitCount==24)
{
int pitch=width%4;
// bgr
if(height>0)
{//height>0 表示图片颠倒
for(int i=0;i<height;i++)
{
int realPitch=i*pitch;
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*3+realPitch];
UCHAR g=buffer[(i*width+j)*3+1+realPitch];
UCHAR r=buffer[(i*width+j)*3+2+realPitch];
pDC->SetPixel(j,height-i,RGB(r,g,b));
}
}
}
else
{
for(int i=0;i<0-height;i++)
{
int realPitch=i*pitch;
for(int j=0;j<width;j++)
{
UCHAR b=buffer[(i*width+j)*3+realPitch];
UCHAR g=buffer[(i*width+j)*3+1+realPitch];
UCHAR r=buffer[(i*width+j)*3+2+realPitch];
pDC->SetPixel(j,i,RGB(r,g,b));
}
}
}
}
#pragma endregion 24 bit
this->ReleaseDC(pDC);//释放掉绘制上下文
delete[] buffer;//释放缓冲区
fclose(fp); //关闭BMP文件
}
复制代码
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2009/05/09/1453205.html,如需转载请自行联系原作者