📄 bmp.c
字号:
//**********************************************************************************************
//* 文 件 名 : bmp.c
//*
//* 文件描述 : 图片BMP解码 RGB24 to TFTLCD(RGB16/RGB565)
//*
//* 作 者 : knight
//* 版 本 : V0.01
//* 编 译 器 : IAR EWARM 5.30
//* 日 期 : 2009-10-18
//* 所需支持代码: tft, sd_mmc_spi, partition, fat16
//**********************************************************************************************
#include "bmp.h"
struct Fat16_FS_Struct* Fat16System;
struct Fat16_Dir_Struct* RootDir;
struct Fat16_File_Struct* FileData;
struct Partition_Struct* Partition;
_BMP_Infor BMP_Infor;
u16 tftBuf[TFTScreenWidth * TFTScreenHeight];
u8 isDirOpened=False;
u8 isFileOpened=False;
/**********************************************************************
* 函数 OpenDir --- 打开路径
* 输入参数 Path --- 路径 字符串 (只支持大写)
* 输出参数 无
* 返回值 True --- 打开成功
* False --- 打开失败
**********************************************************************/
u8
OpenDir(char* Path)
{
if(isDirOpened==True)
{
CloseDir();
}
/**********************************************
* 打开分区
***********************************************/
Partition = partition_open( SD_Raw_Read,
SD_Raw_Read_Interval,
SD_Raw_Write,
SD_Raw_Write_Interval,
0
);
if(!Partition)
{
partition_close(Partition);
return False;
}
/**********************************************
* 打开文件系统
***********************************************/
Fat16System = Fat16_Open(Partition);
if(!Fat16System)
{
Fat16_Close(Fat16System);
partition_close(Partition);
return False;
}
/**********************************************
* 打开根目录
***********************************************/
struct Fat16_Dir_Entry_Struct Dir;
Fat16_Get_Dir_Entry_Of_Path(Fat16System, Path, &Dir);
RootDir = Fat16_Open_Dir(Fat16System, &Dir);
if(!RootDir)
{
Fat16_Close_Dir(RootDir);
Fat16_Close(Fat16System);
partition_close(Partition);
return False;
}
else
{
isDirOpened=True;
return True;
}
}
/**********************************************************************
* 函数 CloseDir --- 关闭路径
* 输入参数 无
* 输出参数 无
* 返回值 无
**********************************************************************/
void
CloseDir(void)
{
Fat16_Close_Dir(RootDir);
Fat16_Close(Fat16System);
partition_close(Partition);
isDirOpened=False;
}
/**********************************************************************
* 函数 OpenFile --- 打开文件
* 输入参数 filename --- 文件名称 字符串 (只支持大写)
* 输出参数 无
* 返回值 True --- 打开成功
* False --- 打开失败
**********************************************************************/
u8
OpenFile(u8* filename)
{
if(isFileOpened==True)
{
CloseFile();
}
FileData = Open_File_In_Dir(Fat16System, RootDir,(char*)filename);
if(!FileData)
{
Fat16_Close_File(FileData);
return False;
}
else
{
isFileOpened=True;
return True;
}
}
/**********************************************************************
* 函数 CloseFile --- 关闭已经打开的文件
* 输入参数 FD --- 文件入口地址(句柄)
* 输出参数 无
* 返回值 无
**********************************************************************/
void
CloseFile(void)
{
Fat16_Close_File(FileData);
isFileOpened=False;
}
/**********************************************************************
* 函数 BMP_ReadHeader --- 读取BMP 文件头信息
* 输入参数 FD --- 文件入口地址(句柄)
* 输出参数 无
* 返回值 True --- 读取成功
* False --- 读取失败
**********************************************************************/
u8
BMP_ReadHeader(void)
{
u8 buf[HeaderCnt];
u16 Cnt;
s32 Offset=0;
Fat16_Seek_File(FileData, &Offset,FAT16_SEEK_SET);
Cnt=Fat16_Read_File(FileData, buf, HeaderCnt);
if (Cnt!=HeaderCnt)
{
return False;
}
BufCopy_8(BMP_Infor.buf,buf,HeaderCnt);
#if 0
///测试读取文件信息
USART_SendBuffer(USART1,"\r\n///-----------------------------------",MaxBufLen);
USART_SendBuffer(USART1,"\r\n///Get BMP Header Information ",MaxBufLen);
USART_SendBuffer(USART1,"\r\n///-----------------------------------",MaxBufLen);
///File_Header.BMP_Type
USART_SendBuffer(USART1,"\r\n File_Header.BMP_Type=0x",MaxBufLen);
Int16ToStr_Hex(BMP_Infor.Infor.File_Header.BMP_Type,buf);
USART_SendBuffer(USART1,buf,4);
///File_Header.BMP_Size
USART_SendBuffer(USART1,"\r\n File_Header.BMP_Size=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.File_Header.BMP_Size,buf);
USART_SendBuffer(USART1,buf,8);
///File_Header.BMP_Offet_Bytes
USART_SendBuffer(USART1,"\r\n File_Header.BMP_Offet_Bytes=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.File_Header.BMP_Offet_Bytes,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.SizeOfHeader
USART_SendBuffer(USART1,"\r\n Infor_Header.SizeOfHeader=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.SizeOfHeader,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.BMP_Width
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_Width=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_Width,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.BMP_Height
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_Height=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_Height,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.BMP_BitCount
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_BitCount=0x",MaxBufLen);
Int16ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_BitCount,buf);
USART_SendBuffer(USART1,buf,4);
///Infor_Header.BMP_Compression
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_Compression=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_Compression,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.BMP_DataSize
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_DataSize=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_DataSize,buf);
USART_SendBuffer(USART1,buf,8);
///Infor_Header.BMP_ColorCnt
USART_SendBuffer(USART1,"\r\n Infor_Header.BMP_ColorCnt=0x",MaxBufLen);
Int32ToStr_Hex(BMP_Infor.Infor.Infor_Header.BMP_ColorCnt,buf);
USART_SendBuffer(USART1,buf,8);
USART_SendBuffer(USART1,"\r\n///----------------End------------------\r\n",MaxBufLen);
#endif
return True;
}
/**********************************************************************
* 函数 ReadBMPData --- 读取BMP图片数据 到缓存
* 输入参数 buf --- 存放数据缓存
* addr--- 图片起始地址, 当 addr<0 时 默认为上次光标地址
* len --- 读取长度
* 输出参数 无
* 返回值 实际读取的字节数
**********************************************************************/
s16
ReadBMPData(u8* buf,s32 addr, u16 len)
{
if (!(addr<0))
{
s32 Offset=BMP_Infor.Infor.File_Header.BMP_Offet_Bytes + addr;
Fat16_Seek_File(FileData, &Offset,FAT16_SEEK_SET);
}
s16 Cnt=Fat16_Read_File(FileData, buf, len);
return Cnt;
}
/**********************************************************************
* 函数 BMP24_To_BMP16 --- 把BMP24转换成BMP16格式(1像素)
* 输入参数 RGB24 --- RGB24位位图格式
* 输出参数 无
* 返回值 16位位图格式
**********************************************************************/
u16
BMP24_To_BMP16(_RGB_BMP24 RGB24)
{
u16 R,G,B;
R=(RGB24.R)*R16max/R24max;
G=(RGB24.G)*R16max/R24max;
B=(RGB24.B)*R16max/R24max;
return (R<<11)|(G<<5)|B;
}
#define LeftOffset 2
#define BottomOffset 2
/**********************************************************************
* 函数 ShowBMP24 --- 显示RGB 24位位图格式图片
* 输入参数 X,Y --- 图片起始点坐标
* 当X<0时 左右置中
* 当Y<0时 上下置中
* filename --- 图片文件 字符串 (只支持大写)
* isClr --- 是否清屏
* 输出参数 无
* 返回值 True --- 显示成功
* False --- 显示失败
**********************************************************************/
u8
ShowBMP24(s16 X,s16 Y,u8* filename,u8 isClr)
{
u32 i,n;
_RGB_buf24 RGB24;
u8 dataH,dataL,fillCnt=0;
u16 data;
s16 pX,pY,width,height;
if (!OpenFile(filename))
{
return False;
}
if (!BMP_ReadHeader())
{
return False;
}
///判断是否为BMP文件
if (BMP_Infor.Infor.File_Header.BMP_Type!=0x4D42)
{
return False;
}
///判断是否为 RGB-24位位图格式
if (BMP_Infor.Infor.Infor_Header.BMP_BitCount!=0x18)
{
return False;
}
SetWindowRange(0,0,TFTScreenWidth,TFTScreenHeight);
if (isClr==True)
{
SetWindowRange(0,0,TFTScreenWidth,TFTScreenHeight);
ClrTFT(0,0,TFTScreenWidth*TFTScreenHeight);
}
fillCnt=(BMP_Infor.Infor.Infor_Header.BMP_Width*3)%4;
width=BMP_Infor.Infor.Infor_Header.BMP_Width;
if (fillCnt>0)
{
width+=1;
}
height=BMP_Infor.Infor.Infor_Header.BMP_Height;
if (X<0)
{
pX=( (TFTScreenWidth-width) + 1 ) / 2;
}
else
{
pX=X;
}
if (pX<0) pX=0;
if (Y<0)
{
pY=( (TFTScreenHeight-height) + 1 ) / 2;
}
else
{
pY=Y;
}
if (pY<0) pY=0;
SetWindowRange(pX+LeftOffset,pY+BottomOffset,width,height);
tftWriteCmd(0x22);
n=width*height;
for(i=0;i<n;i++)
{
if (i==0)
{
ReadBMPData(RGB24.Data,i*3,3);
}
else
{
ReadBMPData(RGB24.Data,(-1),3);
}
data=BMP24_To_BMP16(RGB24.BMP);
dataH=(data)/0x100;
dataL=(data)&0xff;
tftWriteData16(dataH,dataL);
}
return True;
}
////////////////////////////////end of BMP drive////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -