基礎(chǔ)篇_3.圖像編碼之Bmp

學(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)容摘自雷神博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容