二、BMP图片显示测试程序设计
1、测试程序结构设计
(1)目的
确认对BMP结构的认识,加深对RGB颜色格式的理解。
能够在液晶上显示一个160 x 128 大小的图片。(正好与液晶的大小相同)
(2)实现方案
添加一个命令mptest。
在命令处理程序中,先打开图片文件,读入前面54个字节。检查“BM”标志,如果不是BMP退出。
将BMP文件的主要信息读入BMPINFO结构体,如果文件是压缩过的,也不支持,退出程序。
从127行开始,一行一行的读取位图的点阵数据,送液晶显示。
(3)程序结构和流程设计
先添加命令mptest及其处理程序。
在处理程序中,主要作如下处理:
res = f_open ( &BmpFile, (const char *)BmpStr, FA_READ);//打开文件
res = f_read ( &BmpFile, (void *)UserBuf, 54, &ByteRead); //先读开始54字节,BMP文件头一般都这么大;
if ( LOAD_U16 ( UserBuf + BMPHEAD_FLAG )!= BMP_FLAG ){//判断是否为BMP文件
Uart_PutString ( "File Format does't surport!" );
return; } //对比开头两个字节是否“BM”。
PicInfo.DataOffset=LOAD_U32(UserBuf+BMPHEAD_DATAOFFSET );//图像点阵数据区在文件中的偏移。
PicInfo.ColorOffset = LOAD_U32 ( UserBuf + BMPHEAD_INFHEADSIZE ) + 14; //图像颜色表在文件中的偏移 = 信息头的大小+ BMP文件头14个字节。一般为54字节。
PicInfo.BmpWidth = LOAD_U32 ( UserBuf + BMPHEAD_WIDTH );//图像的像素宽度
PicInfo.BmpHeight = LOAD_U32 ( UserBuf + BMPHEAD_HEIGHT ); //图像的像素高度。
PicInfo.BitPerPixel = LOAD_U16 ( UserBuf + BMPHEAD_BITPERPIXEL ); //每个像素占用的位数,真彩色24位,3个字节
PicInfo.Compressed = LOAD_U32 ( UserBuf + BMPHEAD_COMPRESSED ); //图像数据是否被压缩。
PicInfo.BytePerRow //每行像素占用字节数,因为4字节对齐,需要专门计算。
= (u32) ( (u32)( ( ( PicInfo.BmpWidth*PicInfo.BitPerPixel/8 ) + 3 )/4 )*4 ) ;
//从127行开始,一行一行的读取位图的点阵数据,送液晶显示。
for ( Row = 128; Row > 0; Row-- ){ //一行一行倒序扫描
for ( Col = 0; Col < 160; Col++ ){ // 一行160个像素扫描
PixelOffset = PicInfo.DataOffset + ( PicInfo.BmpHeight - Row )\ * PicInfo.BytePerRow + ( PicInfo.BitPerPixel * Col )/8; //根据像素所在行列、每像素位数计算像素数据在文件中的偏移
res = f_lseek ( &BmpFile, PixelOffset );
res = f_read (&BmpFile, (void *)UserBuf, 3, &ByteRead); //在测试命令中,固定读取24位真彩色图,因此一次读取3个字节。
PixelColor =
(u16) ((UserBuf[0]>>3) + ( UserBuf[1]&0xFC )*8 + ( UserBuf[2]&0xF8)*256 ); //24位RGB格式转换为16位的 R:G:B = 5:6:5格式
LCD_SetPixel ( Col, Row-1, PixelColor );//送液晶显示
}
}。