圖片解碼首先是最簡單的bmp圖片解碼,關于bmp的結構可自行查閱,代碼如下
#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 //無壓縮
#define BI_RLE8 1L //每個像素四個bit
#define BI_RLE4 2L //每個像素8個bit
#define BI_BITFIELDS 3L //每個像素的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個字節(jié)
typedef __packed struct
{
WORD bfType ; //文件標志.只對'BM',用來識別BMP位圖類型 2
DWORD bfSize ; //文件大小,占四個字節(jié) 4
WORD bfReserved1 ;//保留 2
WORD bfReserved2 ;//保留 2
DWORD bfOffBits ; //從文件開始到位圖數(shù)據(jù)(bitmap data)開始之間的的偏移量,這一段中存放的就是文件信息 4
}BITMAPFILEHEADER ; //位圖文件頭
//位圖信息頭
typedef __packed struct
{
DWORD biSize ; //說明BITMAPINFOHEADER結構所需要的字數(shù)。
LONG biWidth ; //說明圖象的寬度,以象素為單位
LONG biHeight ; //說明圖象的高度,以象素為單位
WORD biPlanes ; //為目標設備說明位面數(shù),其值將總是被設為1
WORD biBitCount ; //說明比特數(shù)/象素,其值為1、4、8、16、24、或32
DWORD biCompression ; //說明圖象數(shù)據(jù)壓縮的類型。其值可以是下述值之一:
/*BI_RGB:沒有壓縮;
*BI_RLE8:每個象素8比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成(重復象素計數(shù)和顏色索引);
*BI_RLE4:每個象素4比特的RLE壓縮編碼,壓縮格式由2字節(jié)組成
*BI_BITFIELDS:每個象素的比特由指定的掩碼決定。*/
DWORD biSizeImage ;//說明圖象的大小,以字節(jié)為單位。當用BI_RGB格式時,可設置為0
LONG biXPelsPerMeter ;//說明水平分辨率,用象素/米表示
LONG biYPelsPerMeter ;//說明垂直分辨率,用象素/米表示
DWORD biClrUsed ; //說明位圖實際使用的彩色表中的顏色索引數(shù)
DWORD biClrImportant ; //說明對圖象顯示有重要影響的顏色索引的數(shù)目,如果是0,表示都重要。
}BITMAPINFOHEADER;
//顏色索引表,每個顏色索引占4個字節(jié),16位以及以下才會有這個數(shù)據(jù) 也就是說 最多65535個數(shù)據(jù)
//當然,最好不要用16位色的,浪費空間
typedef __packed struct
{
BYTE rgbBlue ; //指定藍色強度
BYTE rgbGreen ; //指定綠色強度
BYTE rgbRed ; //指定紅色強度
BYTE rgbReserved ;//保留,設置為0
}RGBQUAD ;
BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey);
#endif
u8 bmpbuffer[1024] = {0}; //存儲bmp文件的數(shù)組
//解碼這個BMP文件
//設定顯示起始位置以及終止位置
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; //用于標記顏色位
u16 index = 0; //讀取文件信息時候用來定位
u16 uitemp = 0; //記錄實際數(shù)據(jù)一行有多少個點
u16 xtemp = 0;
u16 ytemp = 0; //顯示時輔助計數(shù)
u16 colortemp = 0; //顏色緩沖
res=f_open(&f_bmp,(const TCHAR*)filename,FA_READ); //打開文件
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ù)段開始地址
//獲取位圖信息頭
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;
//所有信息得到,這里應該進行測試了
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++;