BMPビットマップデータを読み取るC ++メソッド

画像ファイルは、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、coroutine、DPDKなど。複数のナレッジポイントが乾物学習教材とグループ960994558)

おすすめ

転載: blog.csdn.net/weixin_52622200/article/details/110392243