STM32单片机图片解码

图片解码首先是最简单的bmp图片解码,关于bmp的结构可自行查阅,代码如下
#ifndef __BMPDECODE_H_
#define __BMPDECODE_H_


#include "ff.h"
#include "lcd.h"
#include "stdlib.h"
#include "usb_type.h"


//重定义区
typedef charchar;//数据类型重定义 , 便于移植
typedef shortSHORT;
//typedef intLONG;
//typedef unsigned intDWORD;
typedef intBOOL;
typedef u8BYTE;
typedef unsigned short WORD;


//#define FALSE 0
//#define TRUE 1


//BMP图象数据压缩的类型
#define BI_RGB0L//无压缩
#define BI_RLE81L//每个像素四个bit
#define BI_RLE42L//每个像素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个字节
typedef __packed struct
{
WORD bfType ;//文件标志.只对'BM',用来识别BMP位图类型 2
DWORD bfSize ;//文件大小,占四个字节4
WORD bfReserved1 ;//保留2
WORD bfReserved2 ;//保留2
DWORD bfOffBits ; //从文件开始到位图数据(bitmap data)开始之间的的偏移量 , 这一段中存放的就是文件信息 4
}BITMAPFILEHEADER ;//位图文件头


//位图信息头
typedef __packed struct
{
DWORD biSize ;//说明BITMAPINFOHEADER结构所需要的字数 。
LONG biWidth ;//说明图象的宽度 , 以象素为单位
LONG biHeight ;//说明图象的高度 , 以象素为单位
WORD biPlanes ;//为目标设备说明位面数 , 其值将总是被设为1
WORD biBitCount ;//说明比特数/象素 , 其值为1、4、8、16、24、或32
DWORD biCompression ; //说明图象数据压缩的类型 。其值可以是下述值之一:
/*BI_RGB:没有压缩;
*BI_RLE8:每个象素8比特的RLE压缩编码 , 压缩格式由2字节组成(重复象素计数和颜色索引);
*BI_RLE4:每个象素4比特的RLE压缩编码 , 压缩格式由2字节组成
*BI_BITFIELDS:每个象素的比特由指定的掩码决定 。*/
DWORD biSizeImage ;//说明图象的大小 , 以字节为单位 。当用BI_RGB格式时 , 可设置为0
LONG biXPelsPerMeter ;//说明水平分辨率 , 用象素/米表示
LONG biYPelsPerMeter ;//说明垂直分辨率 , 用象素/米表示
DWORD biClrUsed ;//说明位图实际使用的彩色表中的颜色索引数
DWORD biClrImportant ; //说明对图象显示有重要影响的颜色索引的数目 , 如果是0 , 表示都重要 。
}BITMAPINFOHEADER;


//颜色索引表 , 每个颜色索引占4个字节 , 16位以及以下才会有这个数据 也就是说 最多65535个数据
//当然 , 最好不要用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文件的数组


//解码这个BMP文件
//设定显示起始位置以及终止位置
BOOL BmpDecode(u8 *filename,u16 sx,u16 sy,u16 ex,u16 ey)
{
FIL f_bmp;//文件系统变量 , 用于读取bmp文件
u16 filereadnum = 0;//用于记录文件字节读取数量
FRESULT res;//文件读取返回信息
BITMAPFILEHEADER bmpfileHead; //位图文件头
BITMAPINFOHEADER bmpinfoHead; //位图信息头
u8 colorByte = 0;//用于标记颜色位
u16 index = 0;//读取文件信息时候用来定位
u16 uitemp = 0;//记录实际数据一行有多少个点
u16 xtemp = 0;
u16 ytemp = 0;//显示时辅助计数
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);//数据段开始地址
//获取位图信息头
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;//颜色位数 16 / 24 / 32 得到2/3/4
if((bmpinfoHead.biWidth%4) != 0)//不是4的倍数
{
uitemp = (((bmpinfoHead.biWidth/4) + 1) * 4);
}
else//是4的倍数
{
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++;
【STM32单片机图片解码】

    推荐阅读