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

