MFC读取24位BMP图片和8位bmp图片

1.对于BMP图像的个人理解

一张BMP图像通常包含4部分,文件头BITMAPFILEHEADER,信息头BITMAPINFOHEADER,颜色表,实际数据。

其中读取24位图像(biBitcount=24)和8位图像(biBitcount==8)的区别就是24位图像颜色表为空,而8位图像则含有256种颜色。

话不多说直接上代码。

2.基于VS2012 mfc的bmp图像读取代码

//定义变量
    BITMAPFILEHEADER Fileheader;//文件头
    BITMAPINFOHEADER Infoheader;//信息头
    BITMAPINFO * pBmpInfo ;//(该变量我也没整明白是干嘛的显示的时候用到,不知道为啥要用这个,不用信息头)
    int bmpwidth;//图像宽高
    int bmpheight;//
    unsigned char *pBmpbuf;//图像指针
    RGBQUAD *pColorTable;//颜色表
    int biBitcount;//图像类型每个像素位数

//定义函数

    bool readBmp(CString bmpName);//读图函数

    void DisplayBmp();//显示图像

/源代码
void CMy20190812ReadimageDlg::OnBnClickedButtonreadimage()
{
    // TODO: 在此添加控件通知处理程序代码
    CString strFileName;//记录选择文件路径  
    strFileName="E:/系统学习/opencv/相关图像/5.bmp";

    bool readinage =readBmp(strFileName);

    if (!readinage)
    {
        AfxMessageBox("读取图像失败!");
    }


    DisplayBmp();
    

}

bool CMy20190812ReadimageDlg:: readBmp(CString bmpName)
{

    FILE *fp;
    fp=fopen(bmpName,"rb");


    if (fp==0) return 0;
    //跳过头文件
    //    函数功能是把文件指针指向文件的开头,需要包含头文件stdio.h
    //
    //        fseek
    //函数名: fseek
    //     功 能: 重定位流上的文件指针
    //     用 法: int fseek(FILE *stream, long offset, int fromwhere);
    //    描 述: 函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere为基准,偏移offset个字     节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。
    fseek(fp,sizeof(BITMAPFILEHEADER),0);

    //        fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0。
    //函数原型
    //size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;
    //参 数
    //buffer 用于接收数据的内存地址
    //size 要读的每个数据项的字节数,单位是字节
    //count 要读count个数据项,每个数据项size个字节.
    //stream 输入流
    //返回值
    //返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。若其他stream或buffer为空指针,或在unicode模式中写入的字节数为奇数,此函数设置errno为EINVAL以及返回0.

    fread(&Infoheader,sizeof(BITMAPINFOHEADER),1,fp);

     bmpwidth=Infoheader.biWidth;
    bmpheight=Infoheader.biHeight;
    biBitcount=Infoheader.biBitCount;


    pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];  
        if (!pBmpInfo)  
    {   
        AfxMessageBox("memory error!");   
        return 0;  
    }   
        if (biBitcount==8)
    {
        pColorTable=new RGBQUAD[256];
        fread(pColorTable,sizeof(RGBQUAD),256,fp);
    }
    

    memcpy(pBmpInfo,&Infoheader,sizeof(BITMAPINFOHEADER));  
        //计算每行所占的字节数

    int lineByte=(bmpwidth*biBitcount/8+3)/4*4;


    pBmpbuf=new unsigned char[lineByte * bmpheight];

    fread(pBmpbuf,1,lineByte * bmpheight,fp);


    fclose(fp);

    return 1;
}

void CMy20190812ReadimageDlg::DisplayBmp()
{

    
    CRect rect;//定义矩形类    

    CWnd *pWnd=GetDlgItem(IDC_STATIC_PIC1);//获得pictrue控件窗口的句柄  

    pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域  
    CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC     

    //显示图片  
    pDC->SetStretchBltMode(COLORONCOLOR);   
    StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpwidth,bmpheight,pBmpbuf,pBmpInfo,DIB_RGB_COLORS,SRCCOPY); 
}

你可能感兴趣的:(BMP图像读取)