运行测试效果:
代码:
- 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文件
- }