C++读取BMP位图数据的方法

图片文件是有固定格式的,像BMP图片:文件头+位图的颜色数据。

文件头一般在读取的时候是使用下面的代码:

BITMAPFILEHEADER fileheader={0}; 
    fread(&fileheader,sizeof(fileheader),1,fp); 
    if(fileheader.bfType!=0x4D42)  // 判断是否为BMP图片
    { 
        fclose(fp); 
        return ; 
    } 
 
    BITMAPINFOHEADER head; 
    fread(&head,sizeof(BITMAPINFOHEADER),1,fp);  
    long bmpWidth = head.biWidth;  //获取图片的宽
    long bmpHeight = head.biHeight;  //获取图片的宽
    WORD biBitCount = head.biBitCount; 
    if(biBitCount != 24) // 是否为24位位图
    { 
        ::AfxMessageBox(_T("请选择24位位图!")); 
        fclose(fp); 
        return ; 
    } 

文件读到这里了就要读到位图的颜色数据了,那么在读取前,我们需要知道数据的大小,这样才能把分配具体大学的缓冲区,之后把数据完整的读取到缓冲区内。

那么计算位图数据的大小一般用下面的代码去做。

int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; 
BYTE *pBmpBuf = new BYTE[totalSize];

在这些工作做完之后,我们就使用fread命令直接读取文件内容即可,直到读到文件结束。

整个具体的代码实现如下:

FILE *fp=NULL; 
    int ret = fopen_s(&fp,"D:\\11.bmp","rb"); 
    if(fp==0)    
    { 
        return ; 
    } 
    BITMAPFILEHEADER fileheader={0}; 
    fread(&fileheader,sizeof(fileheader),1,fp); 
    if(fileheader.bfType!=0x4D42) 
    { 
        fclose(fp); 
        return ; 
    } 
 
    BITMAPINFOHEADER head; 
    fread(&head,sizeof(BITMAPINFOHEADER),1,fp);  
    long bmpWidth = head.biWidth; 
    long bmpHeight = head.biHeight; 
    WORD biBitCount = head.biBitCount; 
    if(biBitCount != 24) 
    { 
        ::AfxMessageBox(_T("请选择24位位图!")); 
        fclose(fp); 
        return ; 
    } 
 
    int totalSize = (bmpWidth *biBitCount/8+3)/4*4*bmpHeight; 
    BYTE *pBmpBuf = new BYTE[totalSize]; 
    size_t size = 0; 
    while(true) 
    { 
        int iret = fread(&pBmpBuf[size],1,1,fp); 
        if(iret == 0) 
            break; 
        size = size + iret; 
    } 
    fclose(fp); 
 
    int i,j; 
    CClientDC dc(this); 
    int pitch=bmpWidth%4; 
    for(i=0;i<bmpHeight;i++) 
    { 
        int realPitch=i*pitch; 
        for(j=0;j<bmpWidth;j++) 
        { 
            dc.SetPixel(j,i,RGB( 
                pBmpBuf[(i*bmpWidth+j)*3+2+realPitch], 
                pBmpBuf[(i*bmpWidth+j)*3+1+realPitch], 
                pBmpBuf[(i*bmpWidth+j)*3+realPitch])); 
        } 
    } 
delete [] pBmpBuf; pBmpBuf = NULL;
    return ; 
    

学以致用才是好,以上可能存在有不足的地方欢迎指出讨论。
(更多免费 C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等等多个知识点干货学习资料加群 960994558)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值