C++實(shí)現(xiàn)bmp格式圖像讀寫
bmp格式圖像有一個(gè)特點(diǎn)就是這類數(shù)據(jù)被分為四個(gè)部分:
1.位圖文件頭(Bitmap File Header) ,大小:14字節(jié)
主要包括位圖文件大小和位圖文件類型信息
2.位圖信息頭(Bitmap Info Header),大小:40字節(jié)
主要包括:位圖的寬度和高度,像素為單位、每個(gè)像素所占位數(shù)(1黑白圖像),(4-16色圖)、(8-256色圖)、(24-真彩色圖),新的BMP格式可以支持32位色。 還有其它水平和垂直分辨力(單位:像素/米)等
3.顏色表(Color Map),大?。?個(gè)字節(jié)
三大類:藍(lán)色分量、綠色分量、紅色分量
4.位圖數(shù)據(jù)(Data Body)
對(duì)于2色位圖用1位就可以表示該像素,那么1個(gè)字節(jié)就可以儲(chǔ)存8個(gè)像素的顏色值
對(duì)于16色位圖,用4個(gè)字節(jié)表示一個(gè)像素顏色,那么一個(gè)字節(jié)可以儲(chǔ)存2個(gè)像素顏色值
對(duì)于256色位圖,1個(gè)字節(jié)剛好儲(chǔ)存1個(gè)像素的顏色值
對(duì)于真彩色位圖,則需要3個(gè)字節(jié)才能表示一個(gè)像素的顏色值
1.讀bmp圖像
bool readBmp(char *bmpName)
{
//二進(jìn)制讀方式打開指定的圖像文件
FILE *fp=fopen(bmpName,"rb");
if(fp==0) return 0;
//跳過(guò)位圖文件頭結(jié)構(gòu)BITMAPFILEHEADER
fseek(fp, sizeof(BITMAPFILEHEADER),0);
//定義位圖信息頭結(jié)構(gòu)變量,讀取位圖信息頭進(jìn)內(nèi)存,存放在變量head中
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1,fp);
//獲取圖像寬、高、每像素所占位數(shù)等信息
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
biBitCount = head.biBitCount;
//定義變量,計(jì)算圖像每行像素所占的字節(jié)數(shù)(必須是4的倍數(shù))
int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
//灰度圖像有顏色表,且顏色表表項(xiàng)為256
if(biBitCount==8){
//申請(qǐng)顏色表所需要的空間,讀顏色表進(jìn)內(nèi)存
pColorTable=new RGBQUAD[256];
fread(pColorTable,sizeof(RGBQUAD),256,fp);
}
//申請(qǐng)位圖數(shù)據(jù)所需要的空間,讀位圖數(shù)據(jù)進(jìn)內(nèi)存
pBmpBuf=new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf,1,lineByte * bmpHeight,fp);
//關(guān)閉文件
fclose(fp);
return 1;
}
2.寫bmp圖像
bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height,
int biBitCount, RGBQUAD *pColorTable)
{
//如果位圖數(shù)據(jù)指針為0,則沒(méi)有數(shù)據(jù)傳入,函數(shù)返回
if(!imgBuf)
return 0;
//顏色表大小,以字節(jié)為單位,灰度圖像顏色表為1024字節(jié),彩色圖像顏色表大小為0
int colorTablesize=0;
if(biBitCount==8)
colorTablesize=1024;
//待存儲(chǔ)圖像數(shù)據(jù)每行字節(jié)數(shù)為4的倍數(shù)
int lineByte=(width * biBitCount/8+3)/4*4;
//以二進(jìn)制寫的方式打開文件
FILE *fp=fopen(bmpName,"wb");
if(fp==0) return 0;
//申請(qǐng)位圖文件頭結(jié)構(gòu)變量,填寫文件頭信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;//bmp類型
//bfSize是圖像文件4個(gè)組成部分之和
fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ colorTablesize + lineByte*height;
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
//bfOffBits是圖像文件前三個(gè)部分所需空間之和
fileHead.bfOffBits=54+colorTablesize;
//寫文件頭進(jìn)文件
fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);
//申請(qǐng)位圖信息頭結(jié)構(gòu)變量,填寫信息頭信息
BITMAPINFOHEADER head;
head.biBitCount=biBitCount;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=height;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*height;
head.biWidth=width;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//寫位圖信息頭進(jìn)內(nèi)存
fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);
//如果灰度圖像,有顏色表,寫入文件
if(biBitCount==8)
fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
//寫位圖數(shù)據(jù)進(jìn)文件
fwrite(imgBuf, height*lineByte, 1, fp);
//關(guān)閉文件
fclose(fp);
return 1;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Qt物聯(lián)網(wǎng)管理平臺(tái)之實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù)功能
隨著時(shí)間的增加,存儲(chǔ)的歷史記錄也在不斷增加,如果設(shè)備數(shù)量很多,存儲(chǔ)間隔很短,不用多久,數(shù)據(jù)庫(kù)中的記錄就非常多,至少是百萬(wàn)級(jí)別起步,而且有些用戶還是需要存儲(chǔ)每一次的采集的數(shù)據(jù)。本文將利用Qt實(shí)現(xiàn)自動(dòng)清理早期數(shù)據(jù),需要的可以參考一下2022-07-07
C++解決輸出鏈表中倒數(shù)k個(gè)結(jié)點(diǎn)的問(wèn)題
這篇文章主要給大家介紹了關(guān)于如何利用C++解決輸出鏈表中倒數(shù)k個(gè)結(jié)點(diǎn)的問(wèn)題,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-12-12
C語(yǔ)言中g(shù)etchar(?)?函數(shù)使用詳解
getchar()?字符輸入函數(shù),沒(méi)有參數(shù),從輸入緩沖區(qū)里面讀取一個(gè)字,需要注意一次只能讀取一個(gè)字符,這篇文章主要介紹了C語(yǔ)言中g(shù)etchar函數(shù)使用詳解,需要的朋友可以參考下2022-12-12
C++ Leetcode實(shí)現(xiàn)從英文中重建數(shù)字
本文主要介紹了當(dāng)給你一個(gè)字符串s,其中包含字母順序打亂的用英文單詞表示的若干數(shù)字(0-9)時(shí),如何通過(guò)Leetcode按升序返回原始的數(shù)字。感興趣的童鞋可以來(lái)看看2021-11-11
C語(yǔ)言實(shí)現(xiàn)快速排序算法實(shí)例
快速排序時(shí)間復(fù)雜度為O(nlogn),是數(shù)組相關(guān)的題目當(dāng)中經(jīng)常會(huì)用到的算法,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言實(shí)現(xiàn)快速排序算法的相關(guān)資料,需要的朋友可以參考下2022-06-06

