BMP文件的读取

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文件
原文地址:https://www.cnblogs.com/tianlangshu/p/1989427.html