📄 bmp.c
字号:
/* 解析
"file1.txt" a file on drive 0
"/file1.txt" (same as above)
"dir1/dir2/file1.txt" a file on drive 0
"2:dir3/file2.txt" a file on drive 2
"2:/dir5" a directory on drive 2
"" the root directory on drive 0
"/" (same as above)
"2:" the root directory on drive 2
*/
//支持24bit BMP图片显示
#include "config.h"
#include ".\BMP\BMP.h"
#include "GUI_Private.h"
#include ".\FATFS\src\ff.h"
static U16 _Read16(const U8 ** ppData)
{
const U8 *pData;
U16 Value;
pData = *ppData;
Value = *pData;
Value |= (U16)(*(pData + 1) << 8);
pData += 2;
*ppData = pData;
return Value;
}
static U32 _Read32(const U8 ** ppData)
{
const U8 * pData;
U32 Value;
pData = *ppData;
Value = *pData;
Value |= ( *(pData + 1) << 8);
Value |= ((U32)*(pData + 2) << 16);
Value |= ((U32)*(pData + 3) << 24);
pData += 4;
*ppData = pData;
return Value;
}
static int _GetStep(int *pYSize,int *pY)
{
if(*pYSize>0)
{
*pY=*pYSize-1 ;
return -1 ;
}
else if(*pYSize<0)
{
*pYSize=-*pYSize ;
*pY=0 ;
return 1 ;
}
else
{
return 0 ;
}
}
//BMP文件数据缓冲区
INT8U BMP_Buffer[960];
static bool Get_BMP_Info(char *file, BMP_FILEHEADER *BmpHead)
{
FATFS fs ;
FIL fsrc;
FRESULT res ;
UINT br;
//获取bmp文件长度、宽度等信息
const U8 *pSrc=BMP_Buffer;
//读取bmp文件
f_mount(0,&fs);
// f_mount(1,&fs);
// f_mount(2,&fs);
res=f_open(&fsrc,file,FA_OPEN_EXISTING|FA_READ);
if(res) return FALSE;
res=f_read(&fsrc,BMP_Buffer,sizeof(BMP_Buffer),&br);
if(res) return FALSE;
f_close(&fsrc);
f_mount(0,NULL);
// f_mount(1,NULL);
// f_mount(2,NULL);
//BMP位图文件头
BmpHead->bfType = _Read16(&pSrc);//Offset:0x0000,文件标志.只对'BM',用来识别BMP位图类型
BmpHead->bfSize = _Read32(&pSrc);//Offset:0x0002,文件大小,占四个字节;注意是大字节序还是小字节序,实际BMP格式中是小字节序
BmpHead->bfReserved1 = _Read16(&pSrc);//Offset:0x0006,保留
BmpHead->bfReserved2 = _Read16(&pSrc);//Offset:0x0008,保留
BmpHead->bfOffBits = _Read32(&pSrc);//Offset:0x000A,从文件开始到位图数据(bitmap data)开始之间的的偏移量
//BMP位图信息头
BmpHead->biSize = _Read32(&pSrc);//Offset:0x000E,位图信息头字节数量。一般为0x28,最好取其实际值
BmpHead->biWidth = _Read32(&pSrc);//Offset:0x0012,说明图象的宽度,以象素为单位
BmpHead->biHeight = _Read32(&pSrc);//Offset:0x0016,说明图象的高度,以象素为单位,如果这是一个正数,说明图像数据是从图像左下角到右上角排列的。
BmpHead->biPlanes = _Read16(&pSrc);//Offset:0x001A,为目标设备说明位面数,其值将总是被设为1
BmpHead->biBitCount = _Read16(&pSrc);//Offset:0x001C,说明比特数/象素,其值为1、4、8、16、24、或32
BmpHead->biCompression = _Read32(&pSrc);//Offset:0x001E,说明图象数据压缩的类型 0表示没有压缩
BmpHead->biSizeImage = _Read32(&pSrc);//Offset:0x0022,说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0
BmpHead->biXPelsPerMeter = _Read32(&pSrc);//Offset:0x0026,说明水平分辨率,用象素/米表示,有符号整数
BmpHead->biYPelsPerMeter = _Read32(&pSrc);//Offset:0x002A,说明垂直分辨率,用象素/米表示,有符号整数
BmpHead->biClrUsed = _Read32(&pSrc);//Offset:0x002E,说明位图实际使用的彩色表中的颜色索引数
BmpHead->biClrImportant = _Read32(&pSrc);//Offset:0x0032,说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
printf("\r\n【BMP位图文件头】");
printf("\r\nBmpHead->bfType =0x%0X",BmpHead->bfType);
printf("\r\nBmpHead->bfSize =%d",BmpHead->bfSize);
printf("\r\nBmpHead->bfReserved1 =%d",BmpHead->bfReserved1);
printf("\r\nBmpHead->bfReserved2 =%d",BmpHead->bfReserved2);
printf("\r\nBmpHead->bfOffBits =%d",BmpHead->bfOffBits);
printf("\r\n【BMP位图信息头】");
printf("\r\nBmpHead->biSize =%d",BmpHead->biSize);
printf("\r\nBmpHead->biWidth =%d",BmpHead->biWidth);
printf("\r\nBmpHead->biHeight =%d",BmpHead->biHeight);
printf("\r\nBmpHead->biPlanes =%d",BmpHead->biPlanes);
printf("\r\nBmpHead->biBitCount =%d",BmpHead->biBitCount);
printf("\r\nBmpHead->biCompression =%d",BmpHead->biCompression);
printf("\r\nBmpHead->biSizeImage =%d",BmpHead->biSizeImage);
printf("\r\nBmpHead->biXPelsPerMeter=%d",BmpHead->biXPelsPerMeter);
printf("\r\nBmpHead->biYPelsPerMeter=%d",BmpHead->biYPelsPerMeter);
printf("\r\nBmpHead->biClrUsed =%d",BmpHead->biClrUsed);
printf("\r\nBmpHead->biClrImportant =%d",BmpHead->biClrImportant);
return TRUE;
}
bool GUI_BMP_Draw_From_SD(char *file,int x0,int y0)
{
BMP_FILEHEADER BmpHead;
int Width,Height ;
U16 Type ;
U32 OffBits,Compression ;
FATFS fs;
FIL fsrc;
FRESULT res;
UINT br;
int x=0,y=0,BytesPerLine,Step ;
//获得BMP头文件信息
if(Get_BMP_Info(file, &BmpHead)==FALSE)
{
return FALSE;
}
Type = BmpHead.bfType;
Width = BmpHead.biWidth;
Height = BmpHead.biHeight;
//BitCount = BmpHead.biBitCount;
Compression = BmpHead.biCompression;
//ClrUsed = BmpHead.biClrUsed;
OffBits = BmpHead.bfOffBits;//bmp颜色数据起始位置
if((Type!=0x4d42)||(Compression))
{
printf("\r\n不支持该图片显示!");
return FALSE;
}
//if((Width>320)||(Height>240))
if(Width>320)//图片宽度不能超过320,因为缓冲数组为960
{
printf("\r\n图片太大,无法显示!");
return FALSE;
}
//开始画图
f_mount(0,&fs);
// f_mount(1,&fs);
// f_mount(2,&fs);
res=f_open(&fsrc,file,FA_OPEN_EXISTING|FA_READ);
if(res) return FALSE;
res=f_lseek(&fsrc,OffBits); //找到bmp颜色数据起始位置
if(res) return FALSE;
Step=_GetStep(&Height,&y); //判断是否从底向上读数据
if(!Step) return FALSE;
BytesPerLine=((24*Width+31)>>5)<<2 ;
for(;(y<Height)&&(y>=0);y+=Step)
{
//每次读取一行数据进行显示,然后再读取下一行数据,行数据个数为BytesPerLine
//对TFT320*240,16bpp,每行320*3=960个字节
res=f_read(&fsrc,BMP_Buffer,BytesPerLine,&br);
if(res) return FALSE;
for(x=0;x<Width;x++)
{
const U8 *pColor=BMP_Buffer+3*x ;
U8 r,g,b ;
//U16 color ;
b=*(pColor);
g=*(pColor+1);
r=*(pColor+2);
LCD_SetPixelIndex(x0+x,y0+y,LCD_Color2Index(((U32)b<<16)|(g<<8)|r));
}
}
f_close(&fsrc);
f_mount(0,NULL);
// f_mount(1,NULL);
// f_mount(2,NULL);
return TRUE;
}
/*************************** End of file ****************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -