學(xué)習(xí)整理的相關(guān)章節(jié)鏈接:
基礎(chǔ)篇_1.音視頻學(xué)習(xí)框架
基礎(chǔ)篇_2. 顏色空間模型 RBG、YUV、HSV
基礎(chǔ)篇_3.圖像編碼之Bmp
基礎(chǔ)篇_4.音頻基礎(chǔ)概念
基礎(chǔ)篇_5.音頻數(shù)據(jù)采集
基礎(chǔ)篇_6.音頻編碼PCM
基礎(chǔ)篇_7.音頻編碼WAV
基礎(chǔ)篇_8.音頻編碼MP3\AAC
BMP(全稱Bitmap)是Windows操作系統(tǒng)中的標準圖像文件格式,可以分成兩類:設(shè)備有向量相關(guān)位圖(DDB)和設(shè)備無向量關(guān)位圖(DIB),使用非常廣。它采用位映射存儲格式,除了圖像深度可選以外,不采用其他任何壓縮,因此,BMP文件所占用的空間很大。BMP文件的圖像深度可選lbit、4bit、8bit及24bit。BMP文件存儲數(shù)據(jù)時,圖像的掃描方式是按從左到右、從下到上的順序。由于BMP文件格式是Windows環(huán)境中交換與圖有關(guān)的數(shù)據(jù)的一種標準,因此在Windows環(huán)境中運行的圖形圖像軟件都支持BMP圖像格式。
格式組成
典型的BMP圖像文件由四部分組成:
1:位圖文件頭數(shù)據(jù)結(jié)構(gòu),它包含BMP圖像文件的類型、顯示內(nèi)容等信息;
typedef struct tagBITMAPFILEHEADER
{
unsigned short int bfType; //位圖文件的類型,必須為BM
unsigned long bfSize; //文件大小,以字節(jié)為單位
unsigned short int bfReserverd1; //位圖文件保留字,必須為0
unsigned short int bfReserverd2; //位圖文件保留字,必須為0
unsigned long bfbfOffBits; //位圖文件頭到數(shù)據(jù)的偏移量,以字節(jié)為單位
}BITMAPFILEHEADER;
2:位圖信息頭數(shù)據(jù)結(jié)構(gòu),它包含有BMP圖像的寬、高、壓縮方法,以及定義顏色等信息;
typedef struct tagBITMAPINFOHEADER
{
long biSize; //該結(jié)構(gòu)大小,字節(jié)為單位
long biWidth; //圖形寬度以象素為單位
long biHeight; //圖形高度以象素為單位
short int biPlanes; //目標設(shè)備的級別,必須為1
short int biBitcount; //每個像素所需的位數(shù),必須是1(雙色)
//4(16色),8(256色)16(高彩色)或24(真彩色)之一
short int biCompression; //位圖的壓縮類型
long biSizeImage; //位圖的大小,以字節(jié)為單位
long biXPelsPermeter; //位圖水平分辨率,每米像素數(shù)
long biYPelsPermeter; //位圖垂直分辨率,每米像素數(shù)
long biClrUsed; //位圖實際使用的顏色表中的顏色數(shù)
long biClrImportant; //位圖顯示過程中重要的顏色數(shù)
}BITMAPINFOHEADER;
3:調(diào)色板,這個部分是可選的,有些位圖需要調(diào)色板,有些位圖,比如真彩色圖(24位的BMP)就不需要調(diào)色板;
typedef struct tagRGBQUAD{
unsigned long bulrgbBlue; // 藍色的亮度(0~255)
unsigned long bulrgbGreen; // 綠色的亮度(0~255)
unsigned long bulrgbRed; // 紅色的亮度(0~255)
unsigned long bulrgbReserved; // 保留,必須位0
}RGBQUAD;
//位圖信息頭和顏色表組成位圖信息,BITMAPINFO結(jié)構(gòu)定義如下:
typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader;//位圖信息頭
RGBQUAD bmiColors[1];//顏色表
} BITMAPINFO;
4:位圖數(shù)據(jù),這部分的內(nèi)容根據(jù)BMP位圖使用的位數(shù)不同而不同,在24位圖中直接使用RGB,而其他的小于24位的使用調(diào)色板中顏色索引值。
5:將RGB24格式像素數(shù)據(jù)封裝為BMP圖像:
BMP圖像內(nèi)部實際上存儲的就是RGB數(shù)據(jù)。本程序?qū)崿F(xiàn)了對RGB像素數(shù)據(jù)的封裝處理。通過本程序中的函數(shù),可以將RGB數(shù)據(jù)封裝成為一張BMP圖像
/**
* Convert RGB24 file to BMP file
* @param rgb24path Location of input RGB file.
* @param width Width of input RGB file.
* @param height Height of input RGB file.
* @param url_out Location of Output BMP file.
*/
int simplest_rgb24_to_bmp(const char *rgb24path,int width,int height,const char *bmppath){
typedef struct
{
long imageSize;
long blank;
long startPosition;
}BmpHead;
typedef struct
{
long Length;
long width;
long height;
unsigned short colorPlane;
unsigned short bitColor;
long zipFormat;
long realSize;
long xPels;
long yPels;
long colorUse;
long colorImportant;
}InfoHead;
int i=0,j=0;
BmpHead m_BMPHeader={0};
InfoHead m_BMPInfoHeader={0};
char bfType[2]={'B','M'};
int header_size=sizeof(bfType)+sizeof(BmpHead)+sizeof(InfoHead);
unsigned char *rgb24_buffer=NULL;
FILE *fp_rgb24=NULL,*fp_bmp=NULL;
if((fp_rgb24=fopen(rgb24path,"rb"))==NULL){
printf("Error: Cannot open input RGB24 file.\n");
return -1;
}
if((fp_bmp=fopen(bmppath,"wb"))==NULL){
printf("Error: Cannot open output BMP file.\n");
return -1;
}
rgb24_buffer=(unsigned char *)malloc(width*height*3);
fread(rgb24_buffer,1,width*height*3,fp_rgb24);
m_BMPHeader.imageSize=3*width*height+header_size;
m_BMPHeader.startPosition=header_size;
m_BMPInfoHeader.Length=sizeof(InfoHead);
m_BMPInfoHeader.width=width;
//BMP storage pixel data in opposite direction of Y-axis (from bottom to top).
m_BMPInfoHeader.height=-height;
m_BMPInfoHeader.colorPlane=1;
m_BMPInfoHeader.bitColor=24;
m_BMPInfoHeader.realSize=3*width*height;
fwrite(bfType,1,sizeof(bfType),fp_bmp);
fwrite(&m_BMPHeader,1,sizeof(m_BMPHeader),fp_bmp);
fwrite(&m_BMPInfoHeader,1,sizeof(m_BMPInfoHeader),fp_bmp);
//BMP save R1|G1|B1,R2|G2|B2 as B1|G1|R1,B2|G2|R2
//It saves pixel data in Little Endian
//So we change 'R' and 'B'
for(j =0;j<height;j++){
for(i=0;i<width;i++){
char temp=rgb24_buffer[(j*width+i)*3+2];
rgb24_buffer[(j*width+i)*3+2]=rgb24_buffer[(j*width+i)*3+0];
rgb24_buffer[(j*width+i)*3+0]=temp;
}
}
fwrite(rgb24_buffer,3*width*height,1,fp_bmp);
fclose(fp_rgb24);
fclose(fp_bmp);
free(rgb24_buffer);
printf("Finish generate %s!\n",bmppath);
return 0;
}
部分內(nèi)容摘自雷神博客