8位灰度圖在LCD上顯示


一、概述

1、灰度

  灰度使用黑色調表示物體,即用黑色為基准色,不同的飽和度的黑色來顯示圖像。每個灰度對象都具有從 0%(白色)到灰度條100%(黑色)的亮度值。 使用黑白或灰度掃描儀生成的圖像通常以灰度顯示。

  像素值量化后用一個字節(8 bits)來表示。如把有黑-灰-白連續變化的灰度值量化為256個灰度級,灰度值的范圍為0~255,表示亮度從深到淺,對應圖像中的顏色為從黑到白。黑白照片包含了黑白之間的所有的灰度色調,每個像素值都是介於黑色和白色之間的256種灰度中的一種。

2、灰度圖

  用灰度表示的圖像稱作灰度圖,灰度圖的RGB三通道滿足關系式:R=G=B。

3、灰度圖bmp文件格式

                 

偏移量

域的名稱

大小

內容

圖像文件頭

0000h

標識符(Identifier)

2 bytes

兩字節的內容用來識別位圖的類型:

BM : Windows 3.1x, 95, NT, 

 

0002h

File Size

1 dword

用字節表示的整個文件的大小

 

0006h

Reserved

1 dword

保留,設置為0

 

000Ah

Bitmap Data Offset

1 dword

從文件開始到位圖數據開始之間的數據

(bitmap data)之間的偏移量

 

000Eh

Bitmap Header Size

1 dword

位圖信息頭(Bitmap Info Header)的長度,用來描述

位圖的顏色、壓縮方法等。下面的長度表示:

28h - Windows 3.1x, 95, NT,

0Ch - OS/2 1.x

F0h - OS/2 2.x

 

0012h

Width

1 dword

位圖的寬度,以像素為單位

 

0016h

Height

1 dword

位圖的高度,以像素為單位

 

001Ah

Planes

1 word

位圖的位面數


圖像信息頭

 

 

001Ch

Bits Per Pixel

1 word

每個像素的位數

1 - Monochrome bitmap

4 - 16 color bitmap

8 - 256 color bitmap

16 - 16bit (high color) bitmap

24 - 24bit (true color) bitmap

32 - 32bit (true color) bitmap

 

001Eh

Compression

1 dword

壓縮說明:

0 - none (也使用BI_RGB表示)

1 - RLE 8-bit / pixel (也使用BI_RLE4表示)

2 - RLE 4-bit / pixel (也使用BI_RLE8表示)

3 - Bitfields (也使用BI_BITFIELDS表示)

 

0022h

Bitmap Data Size

1 dword

用字節數表示的位圖數據的大小。該數必須是4的倍數

 

0026h

HResolution

1 dword

用像素/米表示的水平分辨率

 

002Ah

VResolution

1 dword

用像素/米表示的垂直分辨率

 

002Eh

Colors

1 dword

位圖使用的顏色數。如8-位/像素表示為100h或者 256.

 

0032h

Important Colors

1 dword

指定重要的顏色數。當該域的值等於顏色數時,表示所有

顏色都一樣重要

調色板數據

0036h

Palette

N * 4 byte

調色板規范。對於調色板中的每個表項,這4個字節用下述

方法來描述RGB的值:

  • 1字節用於藍色分量
  • 1字節用於綠色分量
  • 1字節用於紅色分量
  • 1字節用於填充符(設置為0)

圖像數據

0436h

Bitmap Data

x bytes

該域的大小取決於壓縮方法,它包含所有的位圖數據字節

,這些數據實際就是彩色調色板的索引號

 example: gray.bmp

1)gray.bmp的圖片信息

2)grap.bmp文件的數據

0000h: 標示符為“BM”

0002h: 文件大小為0x13036,也就是77878字節

0006h: 保留

000Ah:從文件開頭到位圖數據開始的偏移量為0x436

000Eh: 位圖信息頭的長度為0x28

0012h: 位圖的寬度為0x140,也就是寬320個像素

0016h: 位圖的高度為0xF0,也就是高為240個像素

001Ah: 位圖為1幀

001Ch:像素的位數為8位

001Eh: 圖片無壓縮

0022H: 位圖數據的大小為0x12C00,也就是76800個字節

0026H: 水平分辨率為7200

002Ah: 垂直分辨率為7200

002Eh: 位圖使用的顏色數--該域並未賦值

0032h: 重要的顏色數--該域並未賦值

0036h-0435h: 調色板數據

0436h: 位圖數據區

3)解讀

  位圖數據區保存的是圖片有效的數據,一個字節的存儲單元對應圖片的一個像素,一個字節的數值代表了對應像素的灰度值。本例圖片是寬320*高240,位圖數據區為76800個字節,算上頭部的控制塊為1078個字節,文件總大小為77878字節。

  在顯示的時候,從位圖數據區讀取數據,獲得一個像素的灰度值后,就以灰度值為索引,從調色板區找出灰度值對應的rgb,然后再顯示屏上顯示出該像素。

☆ 注意

  windows規定一個掃描行所占的字節數必須是4的倍數,不足的以0填充。假設一個圖片款318個像素,實際上一行占據了320個字節。

4) bmp文件存儲灰度圖像的順序

  bmp文件存儲圖像的順序是左下角-->右上角,也就是“從下到上,從左到右”。

  那么在顯示bmp圖像時也要遵循這樣的順序,即是:由下而上,由左到右。倘若安裝"從上到下,從左到右",那么顯示的圖像實際上是關於Y軸翻轉的。

測試bmp文件:

WinHex中對應的內容:

二、8位灰度格式轉換到16位565RGB的格式

  灰度圖的RGB通道滿足:R=G=B,以灰度值替換RGB三個通道就得到RGB格式的數據。考慮到LCD顯示器的顯示格式是5:6:5(r:g:b),而灰度值是8位灰階,所以有如下的轉換計算公式:

r = GrayValue/256 * 32 = GrayValue/8 = GrayValue >> 3

g = GrayValue/256 * 64 = GrayValue/4 = GrayValue >> 2

b = GrayValue/256 * 32 = GrayValue/8 = GrayValue >> 3

  8位灰度值轉換為16位的RGB公式為:

#define GRAYTORGB16(t) ((t >> 3)|((t & ~3) << 3)|((t & ~7) << 8))

三、測試程序代碼

/**
  * @brief  顯示灰度圖 
  * @param  x,y : 顯示在LCD上的坐標 
  *         pic_name: 存儲在SD卡根目錄下的灰度文件名
  * @retval None
  */
void Lcd_show_bmp(unsigned short int x, unsigned short int y,char *pic_name)
{
    int i, j;
    int width, height, l_width;    
    BITMAPFILEHEADER bitHead;
    BITMAPINFOHEADER bitInfoHead;
    WORD fileType;
    unsigned int read_num;

    f_mount(0, &bmpfs[0]);
    BMP_DEBUG_PRINTF("file mount ok \r\n");    
    bmpres = f_open( &bmpfsrc , (char *)pic_name, FA_OPEN_EXISTING | FA_READ);    

    if(bmpres == FR_OK)
    {
        BMP_DEBUG_PRINTF("Open file success\r\n");

        /* 讀取文件頭信息  兩個字節*/         
        f_read(&bmpfsrc,&fileType,sizeof(WORD),&read_num);     

        /* 判斷是不是bmp文件 "BM"*/
        if(fileType != 0x4d42)
        {
            BMP_DEBUG_PRINTF("file is not .bmp file!\r\n");
            return;
        }
        else
        {
            BMP_DEBUG_PRINTF("Ok this is .bmp file\r\n");    
        }        

        /* 讀取BMP文件頭信息*/
        f_read(&bmpfsrc,&bitHead,sizeof(tagBITMAPFILEHEADER),&read_num);        
        showBmpHead(&bitHead);

        /* 讀取位圖信息頭信息 */
        f_read(&bmpfsrc,&bitInfoHead,sizeof(BITMAPINFOHEADER),&read_num);        
        showBmpInforHead(&bitInfoHead);
    }    
    else
    {
        BMP_DEBUG_PRINTF("file open fail!\r\n");
        return;
    }    

    width = bitInfoHead.biWidth;
    height = bitInfoHead.biHeight;

    /* 計算位圖的實際寬度並確保它為4的倍數    */
    l_width = WIDTHBYTES(width);
    if(l_width > 320)
    {
        BMP_DEBUG_PRINTF("\n SORRY, PIC IS TOO BIG (<=320)\n");
        return;
    }
    
    /* 設置Lcd Gram 掃描方向為: 右下角-> 左上角 */
    Lcd_GramScan(3);
    
    /* 開一個圖片大小的窗口*/
    LCD_OpenWindow(x, y, width, height);
    
    /* 判斷是否是8bit灰度圖 */
    if(bitInfoHead.biBitCount == 8)
    {
        f_lseek(&bmpfsrc,0x0436);
        
        for(i=0;i< height; i++)
        {      
            /* 讀取一行bmp的數據到數組pColorData里面 */
            f_read(&bmpfsrc,pColorData,l_width,&read_num);

            for(j=0; j<width; j++)                  //一行有效信息
            {
                unsigned short d; 
                d = pColorData[j];
                LCD_WR_Data(GRAYTORGB16(d));        //寫入LCD-GRAM
            } 
        }
    }    
    else 
    {        
        BMP_DEBUG_PRINTF("SORRY, THIS PIC IS NOT A 8BITS GRAY Picture!");
        return ;
    }
    f_close(&bmpfsrc);    
}
View Code

 

參考資料:bmp頭文件和8 bit 灰度圖的顯示

    《STM32庫開發實戰指南》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM