最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言如何讀取bmp圖像

 更新時(shí)間:2022年04月01日 08:58:06   作者:微小冷  
這篇文章主要介紹了C語(yǔ)言如何讀取bmp圖像,BMP即bitmap,由文件頭信息塊、圖像描述信息塊、顏色表、圖像數(shù)據(jù)區(qū)四部分組成,下文更多相關(guān)資料需要的小伙伴可以參考一下

1、BMP圖像編碼

BMP即bitmap,也就是位圖,一般由4部分組成:文件頭信息塊、圖像描述信息塊、顏色表(在真彩色模式無(wú)顏色表)和圖像數(shù)據(jù)區(qū)。

在圖像數(shù)據(jù)之前,如圖所示,共有54位數(shù)據(jù)

其中,0x424d在十進(jìn)制為19778,對(duì)應(yīng)的ASCII碼為BM,表示這是個(gè)bitmap文件。

在C語(yǔ)言中,short類型為16位,即2字節(jié);int為4字節(jié)??紤]到BMP格式的文件頭中,每個(gè)信息基本都是2字節(jié)的倍數(shù),故而用int和short便可描述出bmp格式的文件頭。

文件信息頭[14 bytes]存儲(chǔ)著文件類型,文件大小等信息

// 文件信息頭結(jié)構(gòu)體
typedef struct tagBITMAPFILEHEADER{
? ? unsigned short bfType;?? ??? ?//必為'BM'
? ? unsigned int ? bfSize;?? ??? ?//文件字節(jié)數(shù)(2-5)
? ? unsigned int bfReserved; ? ?//位圖文件保留字,必為0(6-9)
? ? unsigned int ? bfOffBits; ? //像素?cái)?shù)據(jù)偏移 (10-13)
} bmpHeader;

接下來(lái)的40bytes存儲(chǔ)圖像的尺寸,顏色索引,位平面數(shù)等信息

#define uint unsigned int
#define ushort unsigned short
//圖像信息頭結(jié)構(gòu)體
typedef struct tagBITMAPINFOHEADER{
? ? uint ? ?biSize; ? ? ? ? ?// 結(jié)構(gòu)體尺寸 (14-17)
? ? int ? ? biWidth; ? ? ? ? // 圖像寬度 ?(18-21)
? ? int ? ? biHeight; ? ? ? ?// 圖像高度 ?(22-25)
? ? ushort ?biPlanes; ? ? ? ?// 目標(biāo)設(shè)備的級(jí)別,為1(26-27)
? ? ushort ?biBitCount; ? ? ?// 像素位數(shù),為1、4、8或24(28-29)
? ? uint ? ?biCompression; ? // 位圖壓縮類型,0為不壓縮、1為BI_RLE8、2為BI_RLE4(30-33)
? ? uint ? ?biSizeImage; ? ? // 單像素?cái)?shù)據(jù)大小,等于bfSize-bfOffBits (34-37)
? ? int ? ? biXPelsPerMeter; // 水平分辨率,一般為0 (38-41)
? ? int ? ? biYPelsPerMeter; // 垂直分辨率,一般為0 (42-45)
? ? uint ? ?biClrUsed; ? ? ? // 位圖顏色表中的顏色數(shù),0表示使用所有調(diào)色板項(xiàng)(46-49)
? ? uint ? ?biClrImportant; ?// 重要顏色索引的數(shù)目,0表示都重要(50-53)
} infoHeader;

在54位的文件頭之后,如果需要的話,bmp文件可存放調(diào)色板信息,對(duì)于rgb圖像來(lái)說,可以如下

//24位圖像素信息結(jié)構(gòu)體,即調(diào)色板
typedef struct _PixelInfo {
? ? unsigned char rgbBlue; ? //藍(lán)色分量 ?(0-255)
? ? unsigned char rgbGreen; ?//綠色分量 ?(0-255)
? ? unsigned char rgbRed; ? ?//紅色分量 ?(0-255)
? ? unsigned char rgbReserved;// 保留,必須為0
} PixelInfo;

顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個(gè)數(shù)由biBitCount來(lái)確定:

  • 當(dāng)biBitCount=1,4,8時(shí),分別有2,16,256個(gè)表項(xiàng);
  • 當(dāng)biBitCount=24時(shí),沒有顏色表項(xiàng)。

位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下:

typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader; // 位圖信息頭
RGBQUAD bmiColors[1]; ? ? ? // 顏色表
} bmpInfo;

顏色表接下來(lái)為圖像數(shù)據(jù)區(qū),存儲(chǔ)每個(gè)像素對(duì)應(yīng)的顏色號(hào),單像素點(diǎn)顏色號(hào)的位長(zhǎng)度與圖像類型有關(guān)

圖像類型2色圖像16色圖像256色圖像真彩色圖像
字節(jié)數(shù)1bit4bit1B(8bit)3B

由此可知,理想情況下圖像數(shù)據(jù)區(qū)的字節(jié)數(shù)為:

但是,由于BMP以字節(jié)為單位,按行存儲(chǔ)圖片的數(shù)據(jù),也就是說每一行必須為字節(jié)數(shù)。而對(duì)于16色以及2色圖像而言,當(dāng)每行像素個(gè)數(shù)為奇數(shù)時(shí),則必然導(dǎo)致出現(xiàn)空位,從而實(shí)際所占存儲(chǔ)空間要大于上述計(jì)算值。

2、讀取BMP文件

讀取文件之后第一件事即判斷我們讀取的是否為BMP圖像,即

//判斷是否是位圖,在0-1字節(jié)?
int IsBitMap(FILE *fp){
?? ?ushort s;
?? ?fread(&s,1,2,fp);
? ? return s==BM ? 1 : 0;
}?

其中,fread命令表示讀取文件fp,并將讀取到的內(nèi)容存儲(chǔ)在s中。1表示要讀取的數(shù)據(jù)的大小,2表示將要讀取的元素的個(gè)數(shù)。由前文可知,位圖的文件類型必須是BM,十六進(jìn)制下0x4d42,十進(jìn)制為19778。

然后需要得到圖像的寬度和高度,從而確定數(shù)據(jù)區(qū)的范圍

//獲得圖片的寬度,在18-21字節(jié)?
int getWidth(FILE *fp){
?? ?int width;
?? ?fseek(fp,18,SEEK_SET);
?? ?fread(&width,1,4,fp);
?? ?return width;?? ?
}
?
//獲得圖片的高度 ,在22-25字節(jié)?
int getHeight(FILE *fp){
?? ?int height;
?? ?fseek(fp,22,SEEK_SET);
?? ?fread(&height,1,4,fp);
?? ?return height;?? ?
} ?

其中,fseek可以為fp提供一個(gè)偏移量,SEEK_SET表示從文件的開頭進(jìn)行移動(dòng)。由上文可知,圖片高度所在位置是第22個(gè)字節(jié)。

若想讀取其他信息,以此類推即可。

//test.c
#include<stdio.h>
#include<malloc.h>

#define BM 19778?? ??? ?// 位圖的標(biāo)志
#define PATH "1.bmp" ??? ?//打開的文件路徑?
#define ushort unsigned short
#define uint unsigned int
#define uchar unsigned char

//判斷是否是位圖,在0-1字節(jié)?
int IsBitMap(FILE *fp){
?? ?ushort s;
?? ?fread(&s,1,2,fp);
? ? return s==BM ? 1 : 0;
}?
?
//獲得圖片的寬度,在18-21字節(jié)?
int getWidth(FILE *fp){
?? ?int width;
?? ?fseek(fp,18,SEEK_SET);
?? ?fread(&width,1,4,fp);
?? ?return width;?? ?
}
?
//獲得圖片的高度 ,在22-25字節(jié)?
int getHeight(FILE *fp){
?? ?int height;
?? ?fseek(fp,22,SEEK_SET);
?? ?fread(&height,1,4,fp);
?? ?return height;?? ?
} ?
?
//獲得每個(gè)像素的位數(shù),在28-29字節(jié)?
ushort getBit(FILE *fp)
{
?? ?ushort bit;
?? ?fseek(fp,28,SEEK_SET);
?? ?fread(&bit,1,2,fp);
?? ?return bit;
}?
?
//獲得數(shù)據(jù)的起始位置,在10-13字節(jié)
uint getOffSet(FILE *fp){
?? ?uint OffSet;
?? ?fseek(fp,10L,SEEK_SET);
?? ?fread(&OffSet,1,4,fp);
?? ?return OffSet;
}


int main(){
?? ?int width,height;
?? ?FILE *fp=fopen(PATH,"r");
?? ?uchar *r,*g,*b;
?? ?int i,j;
?? ?r=(uchar *)malloc(4000);
?? ?b=(uchar *)malloc(4000);
?? ?g=(uchar *)malloc(4000);
?? ?
?? ?if(!IsBitMap(fp)){
?? ??? ?printf("format error!\n");
?? ??? ?fclose(fp);
?? ??? ?return 0;?
? ? }

? ? printf("this file is a bitmap picture\n");
?? ?printf("width = %ld\nheight = %ld\n",getWidth(fp),getHeight(fp));
?? ?printf("bit size = %d bit\n",getBit(fp));
?? ?printf("OffSet = %d\n",getOffSet(fp));
?? ?
?? ?return 0;
}

驗(yàn)證:

> gcc .\test.c
> .\a.exe     
this file is a bitmap picture
width = 3840
height = 2160
bit size = 24 bit
OffSet = 138

到此這篇關(guān)于C語(yǔ)言如何讀取bmp圖像的文章就介紹到這了,更多相關(guān)C讀取bmp圖像內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++驗(yàn)證哥德巴赫猜想

    c++驗(yàn)證哥德巴赫猜想

    這篇文章主要介紹了c++驗(yàn)證哥德巴赫猜想,哥德巴赫猜想就是任一大于2的偶數(shù),都可表示成兩個(gè)素?cái)?shù)之和,需要的朋友可以參考下
    2014-04-04
  • 貪吃蛇C語(yǔ)言代碼實(shí)現(xiàn)(難度可選)

    貪吃蛇C語(yǔ)言代碼實(shí)現(xiàn)(難度可選)

    這篇文章主要為大家詳細(xì)介紹了貪吃蛇C語(yǔ)言代碼實(shí)現(xiàn),游戲難度可供選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 淺談C++中const與constexpr的區(qū)別

    淺談C++中const與constexpr的區(qū)別

    C++11中新增加了用于指示常量表達(dá)式的constexpr關(guān)鍵字。本文將帶大家詳細(xì)了解一下const與constexpr之間的區(qū)別,需要的小伙伴們可以參考一下
    2021-11-11
  • C++類和對(duì)象補(bǔ)充

    C++類和對(duì)象補(bǔ)充

    類是創(chuàng)建對(duì)象的模板,一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類類型的一個(gè)變量;創(chuàng)建對(duì)象的過程也叫類的實(shí)例化。每個(gè)對(duì)象都是類的一個(gè)具體實(shí)例(Instance),擁有類的成員變量和成員函數(shù)
    2021-10-10
  • C語(yǔ)言棧的表示與實(shí)現(xiàn)實(shí)例詳解

    C語(yǔ)言棧的表示與實(shí)現(xiàn)實(shí)例詳解

    這篇文章主要介紹了C語(yǔ)言棧的表示與實(shí)現(xiàn),對(duì)于數(shù)據(jù)結(jié)構(gòu)與算法的研究有一定的借鑒價(jià)值,需要的朋友可以參考下
    2014-07-07
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧簡(jiǎn)單操作

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧簡(jiǎn)單操作

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之棧簡(jiǎn)單操作的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 超級(jí)詳細(xì)講解C++中的多態(tài)

    超級(jí)詳細(xì)講解C++中的多態(tài)

    多態(tài)是在不同繼承關(guān)系的類對(duì)象,去調(diào)同一函數(shù),產(chǎn)生了不同的行為,下面這篇文章主要給大家介紹了關(guān)于C++中多態(tài)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • 深入理解C++ 空類大小

    深入理解C++ 空類大小

    本文主要介紹了C++ 空類大小,規(guī)定空類大小為1字節(jié),主要是為了保證對(duì)象的唯一性和可區(qū)分性,滿足數(shù)組元素地址連續(xù)的要求,下面就來(lái)了解一下
    2025-01-01
  • C語(yǔ)言中操作密碼文件的一些函數(shù)總結(jié)

    C語(yǔ)言中操作密碼文件的一些函數(shù)總結(jié)

    這篇文章主要介紹了C語(yǔ)言中操作密碼文件的一些函數(shù)總結(jié),包括setpwent()函數(shù)和getpwent()函數(shù)以及endpwent()函數(shù),需要的朋友可以參考下
    2015-08-08
  • C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié)

    C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié)

    這篇文章主要介紹了C語(yǔ)言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié),是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論

安阳县| 汽车| 沂水县| 新巴尔虎右旗| 于都县| 高唐县| 理塘县| 日土县| 资中县| 惠东县| 哈密市| 澄迈县| 永寿县| 衡南县| 鲁山县| 翼城县| 仁怀市| 许昌县| 泰和县| 抚顺市| 德格县| 淮南市| 康马县| 舞钢市| 东宁县| 桓仁| 云安县| 望江县| 彝良县| 阿城市| 六枝特区| 万载县| 鄯善县| 集安市| 双峰县| 石柱| 邵武市| 万山特区| 阳城县| 高淳县| 武宁县|