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)

猜你喜欢

转载自blog.csdn.net/weixin_52622200/article/details/110392243