STM32單片機(jī)圖片解碼
圖片解碼首先是最簡(jiǎn)單的bmp圖片解碼,關(guān)于bmp的結(jié)構(gòu)可自行查閱,代碼如下
#ifndef __BMPDECODE_H_
#define __BMPDECODE_H_
#include "ff.h"
#include "lcd.h"
#include "stdlib.h"
#include "usb_type.h"
//重定義區(qū)
typedef char CHAR; //數(shù)據(jù)類型重定義,便于移植
typedef short SHORT;
//typedef int LONG;
//typedef unsigned int DWORD;
typedef int BOOL;
typedef u8 BYTE;
typedef unsigned short WORD;
//#define FALSE 0
//#define TRUE 1
//BMP圖象數(shù)據(jù)壓縮的類型
#define BI_RGB 0L //無(wú)壓縮
#define BI_RLE8 1L //每個(gè)像素四個(gè)bit
#define BI_RLE4 2L //每個(gè)像素8個(gè)bit
#define BI_BITFIELDS 3L //每個(gè)像素的bit由指定的掩碼決定
#define bufferToLong(buffer,t) (LONG)((((u32)bmpbuffer[t])) + (((u32)bmpbuffer[t+1])<<8) +(((u32)bmpbuffer[t+2])<<16) + (((u32)bmpbuffer[t+3])<<24))
#define bufferToWord(buffer,t) (WORD)(((u32)(buffer[t])) + (((u32)(buffer[t+1]))<<8))
#define bufferToDword(buffer,t) (DWORD)((((u32)bmpbuffer[t])) + (((u32)bmpbuffer[t+1])<<8) +(((u32)bmpbuffer[t+2])<<16) + (((u32)bmpbuffer[t+3])<<24))
#define RGB888buffertoRGB565(buffer,t) ((((u16)buffer[t])>>3) + ((((u16)buffer[t+1])>>2)<<5) + ((((u16)buffer[t+2])>>3)<<11))
//BMP文件頭 14個(gè)字節(jié)
typedef __packed struct
{
WORD bfType ; //文件標(biāo)志.只對(duì)'BM',用來(lái)識(shí)別BMP位圖類型 2
DWORD bfSize ; //文件大小,占四個(gè)字節(jié) 4
WORD bfReserved1 ;//保留 2
WORD bfReserved2 ;//保留 2
DWORD bfOffBits ; //從文件開(kāi)始到位圖數(shù)據(jù)(bitmap data)開(kāi)始之間的的偏移量,這一段中存放的就是文件信息 4
}BITMAPFILEHEADER ; //位圖文件頭
//位圖信息頭
typedef __packed struct
{
DWORD biSize ; //說(shuō)明BITMAPINFOHEADER結(jié)構(gòu)所需要的字?jǐn)?shù)。
LONG biWidth ; //說(shuō)明圖象的寬度,以象素為單位
LONG biHeight ; //說(shuō)明圖象的高度,以象素為單位
WORD biPlanes ; //為目標(biāo)設(shè)備說(shuō)明位面數(shù),其值將總是被設(shè)為1
WORD biBitCount ; //說(shuō)明比特?cái)?shù)/象素,其值為1、4、8、16、24、或32
DWORD biCompression ; //說(shuō)明圖象數(shù)據(jù)壓縮的類型。其值可以是下述值之一:
/*BI_RGB:沒(méi)有壓縮;
*BI_RLE8:每個(gè)象素8比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成(重復(fù)象素計(jì)數(shù)和顏色索引);
*BI_RLE4:每個(gè)象素4比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成
*BI_BITFIELDS:每個(gè)象素的比特由指定的掩碼決定。*/
DWORD biSizeImage ;//說(shuō)明圖象的大小,以字節(jié)為單位。當(dāng)用BI_RGB格式時(shí),可設(shè)置為0
LONG biXPelsPerMeter ;//說(shuō)明水平分辨率,用象素/米表示
LONG biYPelsPerMeter ;//說(shuō)明垂直分辨率,用象素/米表示
DWORD biClrUsed ; //說(shuō)明位圖實(shí)際使用的彩色表中的顏色索引數(shù)
DWORD biClrImportant ; //說(shuō)明對(duì)圖象顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。
}BITMAPINFOHEADER;
//顏色索引表,每個(gè)顏色索引占4個(gè)字節(jié),16位以及以下才會(huì)有這個(gè)數(shù)據(jù) 也就是說(shuō) 最多65535個(gè)數(shù)據(jù)
//當(dāng)然,最好不要用16位色的,浪費(fèi)空間
typedef __packed struct
{
BYTE rgbBlue ; //指定藍(lán)色強(qiáng)度
BYTE rgbGreen ; //指定綠色強(qiáng)度
BYTE rgbRed ; //指定紅色強(qiáng)度
BYTE rgbReserved ;//保留,設(shè)置為0
}RGBQUAD ;
BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey);
#endif
u8 bmpbuffer[1024] = {0}; //存儲(chǔ)bmp文件的數(shù)組
//解碼這個(gè)BMP文件
//設(shè)定顯示起始位置以及終止位置
BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey)
{
FIL f_bmp; //文件系統(tǒng)變量,用于讀取bmp文件
u16 filereadnum = 0; //用于記錄文件字節(jié)讀取數(shù)量
FRESULT res; //文件讀取返回信息
BITMAPFILEHEADER bmpfileHead; //位圖文件頭
BITMAPINFOHEADER bmpinfoHead; //位圖信息頭
u8 colorByte = 0; //用于標(biāo)記顏色位
u16 index = 0; //讀取文件信息時(shí)候用來(lái)定位
u16 uitemp = 0; //記錄實(shí)際數(shù)據(jù)一行有多少個(gè)點(diǎn)
u16 xtemp = 0;
u16 ytemp = 0; //顯示時(shí)輔助計(jì)數(shù)
u16 colortemp = 0; //顏色緩沖
res=f_open(&f_bmp,(const TCHAR*)filename,FA_READ); //打開(kāi)文件
if(res!=FR_OK) return FALSE;
res = f_read(&f_bmp,bmpbuffer,1024,(UINT*)&filereadnum); //讀取文件
if(res!=FR_OK) return FALSE;
//獲取位圖文件頭
bmpfileHead.bfType = (WORD)((((u16)bmpbuffer[0])<<8) + bmpbuffer[1+1]);
bmpfileHead.bfSize = bufferToDword(bmpbuffer,2);
bmpfileHead.bfReserved1 = bufferToWord(bmpbuffer,6);
bmpfileHead.bfReserved2 = bufferToWord(bmpbuffer,8);
bmpfileHead.bfOffBits = bufferToDword(bmpbuffer,10); //數(shù)據(jù)段開(kāi)始地址
//獲取位圖信息頭
bmpinfoHead.biSize = bufferToDword(bmpbuffer,14);
bmpinfoHead.biWidth = bufferToLong(bmpbuffer,18);
bmpinfoHead.biHeight = bufferToLong(bmpbuffer,22);
bmpinfoHead.biPlanes = bufferToWord(bmpbuffer,26);
bmpinfoHead.biBitCount = bufferToWord(bmpbuffer,28); //顏色位
bmpinfoHead.biCompression = bufferToDword(bmpbuffer,30);
bmpinfoHead.biSizeImage = bufferToDword(bmpbuffer,34);
bmpinfoHead.biXPelsPerMeter = bufferToLong(bmpbuffer,38);
bmpinfoHead.biYPelsPerMeter = bufferToLong(bmpbuffer,42);
bmpinfoHead.biClrUsed = bufferToDword(bmpbuffer,46);
bmpinfoHead.biClrImportant = bufferToDword(bmpbuffer,50);
index = bmpfileHead.bfOffBits;
//所有信息得到,這里應(yīng)該進(jìn)行測(cè)試了
colorByte = bmpinfoHead.biBitCount/8; //顏色位數(shù) 16 / 24 / 32 得到2/3/4
if((bmpinfoHead.biWidth%4) != 0) //不是4的倍數(shù)
{
uitemp = (((bmpinfoHead.biWidth/4) + 1) * 4);
}
else //是4的倍數(shù)
{
uitemp = bmpinfoHead.biWidth ;
}
if(colorByte == 3) //24位顏色
{
while(1)
{
if(index <= 1021)
{
colortemp = RGB888buffertoRGB565(bmpbuffer,index);
index = index +3;
if(sx+xtemp LCD_Draw_Point_Buffer(sx+xtemp,sy+ytemp,colortemp); xtemp++; if(xtemp >= uitemp) { xtemp = 0; ytemp++; } } else { if(index == 1022) { if(sx+xtemp LCD_Draw_Point_Buffer(sx+xtemp,sy+ytemp,colortemp); xtemp++;





