BMP文件的读取

运行测试效果:

代码:

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文件
}

posted on 2009-05-09 15:25  Phinecos(洞庭散人)  阅读(2838)  评论(0编辑  收藏  举报

导航