C语言读取bmp图像并做简单显示
生活随笔
收集整理的這篇文章主要介紹了
C语言读取bmp图像并做简单显示
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C語言讀取bmp圖像并做簡單顯示)
- bmp文件格式
- 讀取bmp文件信息并展示
bmp文件格式
bmp文件大體上分為四個部分:
| bmp文件構成 |
|---|
| 位圖文件頭BITMAPFILEHEADER |
| 位圖信息頭BITMAPINFOHEADER |
| 調色板Palette |
| 實際的位圖數據ImageDate |
第一部分為位圖文件頭,位圖文件頭長度固定,為14個字節。
typdef struct {
WORD bfType; //指定文件類型,必須是0x424d,即”BM”
DWORD bfSize; //指定文件大小
WORD bfReserved1; //保留字
WORD bfReserved2; //保留字
DWORD bfOffBits; //為文件頭到實際的位圖數據的偏移字節數,即上圖前三部分和
}bitmapFileHeader;
第二部分為位圖信息頭,這個結構的長度也是固定的,為40個字節。
typedef struct {DWORD biSize; //指這個機構的長度,為40LONG biWidth; //指定圖像的寬度,單位是像素LONG biHeight; //指定圖像的高度,單位是像素WORD biPlanes; //平面數,必須為1,不用考慮 WORD biBitCount; //指定表示顏色是要用到的位數,常用值為1(黑白二色圖),//4(16色圖),8(256色),24(真彩色圖)(新的.bmp格式支持32位色)DWORD biCompression; //指定位圖是否壓縮,有效的值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFILELDSDWORD biSizeImage; //指定實際的位圖數據占用的字節數,其實也可以從以下的公式計算出來://biSizeImage=bitWidth’*biHeight,bitWidth‘為大于等于bitWidth的4的倍數LONG biXPelsPerMeter; //指定設備的水平分辨率,單位是每米的圖像個數LONG biYPelsPerMeter; //同上,垂直分辨率DWORD biClrUsed; //指定本圖像實際用到的顏色數,如果該值為零,則用到的顏色數為2^biBitCountDWORD biClrImportant;// 指定本圖象中重要的顏色數,如果該值為零,則認為所有的顏色都是重要的
}bitmapInfoHeader;
第三部分為調色板(真彩圖像不需要調色版,bitmapInfoHeader后直接是數據)調色板實際是一個數組,共有biClrUsed個元素(如果該值為0,則有2^biBitCount個元素),數組中每個元素的類型是一個RGBQUAD結構,占四個字節,其定義如下:
typedef struct {BYTE rgbBlue; //該顏色的藍色分量BYTE rgbGreen; //該顏色的綠色分量BYTE rgbRed; //該顏色的紅色分量BYTE rgbReserved; //保留值
} RGBQUAD;
第四部分為實際圖像數據
對于用到調色版的位圖,圖像數據就是該像素顏在調色板中的索引值。對于真彩圖,圖像數據就是實際的R、G、B值。
需要注意兩點:
(1)每一行的字節數必須是4的整倍數,如果不是,則需要補齊。
(2)一般來說,.bmp文件的數據是從下到上,從左到右的。也就是說,從文件中最先讀到的是圖象最下面一行的左邊第一個像素,然后是左邊第二個像素……接下來是倒數第二行左邊第一個像素,左邊第二個像素……依次類推 ,最后得到的是最上面一行的最右一個像素。
讀取bmp文件信息并展示
以24位bmp圖像為例
定義數據結構:
typedef struct {unsigned char bfType[2];unsigned long bfSize;unsigned short bfReserved1;unsigned short bfReserved2;unsigned long bfOffBits;
}bitmapFileHeader;typedef struct {unsigned long biSize;long biWidth;long biHeight;unsigned short biPlanes;unsigned short biBitCount;unsigned long biCompression;unsigned long biSizeImage;long biXPixPerMeter;long biYPixPerMeter;unsigned long biClrused;unsigned long biClrImportant;
}bitmapInfoHeader;
讀入文件頭:
//僅展示,不用于實驗
int readFileHeader(FILE *fp,bitmapFileHeader*bfHeader){fseek(fp,0,SEEK_SET);fread(bfHeader,sizeof(bitmapFileHeader),1,fp);/*int i; printf("讀入文件頭:");char*p=(char*)bfHeader;for(i=0;i<sizeof(bitmapFileHeader);i++,p++){printf("%02x ",*p);}printf("\n");printf("文件頭信息如下:\n");printf("文件類型:%c%c\n",bfHeader->bfType[0],bfHeader->bfType[1]);printf("文件大小: %d 字節\n",bfHeader->bfSize);printf("位圖數據偏移:%d\n",bfHeader->bfOffBits);*/return 0;
}
讀信息頭:
//僅展示,不用于實驗
int readInfoHeader(FILE*fp,bitmapInfoHeader*biHeader){fseek(fp,14,SEEK_SET);fread(biHeader,sizeof(bitmapInfoHeader),1,fp);/*int i;printf("讀入位圖信息頭:\n");char*p=(char*)biHeader;for(i=0;i<sizeof(bitmapInfoHeader);i++,p++){printf("%02x ",*p);if(i%20==0&&i!=0)printf("\n");}printf("\n");printf("位圖信息頭信息如下:\n");printf("bmp圖像寬度:%d\n",biHeader->biWidth);printf("bmp圖像高度:%d\n",biHeader->biHeight);printf("bmp圖像顏色位數: %d\n",biHeader->biBitCount);printf("bmp圖像實際數據占用字節:%d\n",biHeader->biSizeImage);*/return 0;
}
讀入bmp圖像數據,并展示:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>#pragma pack(1) //這個選項挺重要,不加的話程序就會報錯,原因參考
//https://blog.csdn.net/qq_44310495/article/details/109181857typedef struct {unsigned char bfType[2];unsigned long bfSize;unsigned short bfReserved1;unsigned short bfReserved2;unsigned long bfOffBits;
}bitmapFileHeader;typedef struct {unsigned long biSize;long biWidth;long biHeight;unsigned short biPlanes;unsigned short biBitCount;unsigned long biCompression;unsigned long biSizeImage;long biXPixPerMeter;long biYPixPerMeter;unsigned long biClrused;unsigned long biClrImportant;
}bitmapInfoHeader;int main(){FILE *fp,*fp_txt;if((fp=fopen("d:\Temp\\skull.bmp","rb"))==NULL){perror("can not open file!");return -1;}bitmapFileHeader bfHeader;fread(&bfHeader,14,1,fp);bitmapInfoHeader biHeader;fread(&biHeader,40,1,fp);int imSize=biHeader.biSizeImage;int width=biHeader.biWidth;int height=biHeader.biHeight;int bitCount=biHeader.biBitCount;fseek(fp,bfHeader.bfOffBits,SEEK_SET);unsigned char*imageData=(unsigned char*)malloc(imSize*sizeof(unsigned char));fread(imageData,imSize*sizeof(unsigned char),1,fp);//圖像為24位圖像int lineBytes=(bitCount*width+31)/32*4;//得到圖像數據的bitwidth'int i,j;int r,g,b;for(i=0;i<height;i++){ //對于每一行for(j=0;j<width*3;j++){ //對于每一列r=*(imageData+lineBytes*(height-1-i)+j); //從最后一行往上讀j++;g=*(imageData+lineBytes*(height-1-i)+j);j++;b=*(imageData+lineBytes*(height-1-i)+j);if(r==255&&g==255&&b==255) //模擬二值圖像展示printf(" ");elseprintf(".$");}printf("\n");}free(imageData);fclose(fp);getchar();return 0;
}
代碼效果展示:
總結
以上是生活随笔為你收集整理的C语言读取bmp图像并做简单显示的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言中的struct结构体对齐问题
- 下一篇: gvgai框架搭建及controller