上一次讲到ZYNQ开发板SD卡读写操作,但是里面的读写操作比较简单,现在学习了一下关于SD卡读取BMP文件的操作,在这里进行一下总结。
本文主要参考了以下一些博客、网页:
[1].http://blog.csdn.net/o_sun_o/article/details/8351037
[2].http://blog.csdn.net/love_ljq/article/details/79117738
[3].黑金开发板源码
这个文章的主要架构跟上一节SD卡简单读写相似,关于ZYNQ系统搭建的我就不在这里细讲了,把参考[2]先实现了之后再来看这篇文章,在这篇文章里面呢,就是自己实现了一个bmp_load函数。
首先我们需要准备一张图片,网上随便找一张图片,然后把这张图片裁成200x200大小,并且设置为灰度图像,我之前打算用Windows自带的画图来将图片转换为灰度图像的,但是发现转换出来的图像跟我想象中的不一样,于是我用Matlab实现了。原因似乎是这样的,原来的这张图片是三通道彩色图,虽然看起来是灰度图,另存为256色图并不是转换为灰度图,而且三通道共计256色,所以就是说另存为256色并不是转换为灰度图,而我们用Matlab实现的则是转换为灰度图了。把得到的灰度图像放到SD卡根目录下边。
下面讲一下关于BMP图片的图片格式,学过相关知识的同学应该都知道,图片是由文件头以及图片数据构成的,文件头里面包含了比如图片的格式,图片的大小等的信息,关于这部分的知识,主要参考了[1],大家有兴趣的话也可以了解一下,对于我们事先从SD卡进行BMP图片读取的话,要了解的主要是图像的大小,图像的起始位置这些信息。我们首先读取文件头的前54个字符,这里面有很多有用的信息,图像的长宽放在[18][19],[20][21]这些位置,而图像的起始位置在[10][11]这些位置,也就是通过读取[10][11]的值可以确定图像数据的第一个像素点值。
要注意是是,图像读取出来的第一个像素值的Value值是图像左下角的像素值,并不是我们常识中认为的左上方的第一个像素点的值,而最后一个像素值是右上角的值,在BMP文件中,图像是从下到上,从左到右来进行读取的。
以下是源代码
#include "platform.h"
#include "xparameters.h"
#include "xil_printf.h"
#include "ff.h"
#include "xdevcfg.h"
#include
static FATFS fatfs;
int SD_Init()
{
FRESULT rc;
rc = f_mount(&fatfs,"",0);
if(rc)
{
xil_printf("ERROR: f_mount returned %d\r\n",rc);
return XST_FAILURE;
}
return XST_SUCCESS;
}
void bmp_load(char *bmp,u8 *frame,)
{
short y,x;
short XImage,YImage;
FIL fil;
u32 iPixelAddr = 0;
FRESULT res;
unsigned char TMPBUF[64];
u32 br;
res = f_open(&fil,bmp,FA_OPEN_EXISTING | FA_READ);
if(res != FR_OK)
{
return;
}
res = f_read(&fil,&TMPBUF,54,&br);
xil_printf("brValue:%d",br);
if(res != FR_OK)
{
return;
}
XImage = (unsigned short int)TMPBUF[19]*256 + TMPBUF[18]; //这里计算的是图像的Width和Height
YImage = (unsigned short int)TMPBUF[23]*256 + TMPBUF[22];
xil_printf("Begin%d ",TMPBUF[11]);xil_printf("%dEnd",TMPBUF[10]); //这里表明前多少数据是无效的
xil_printf("%d",XImage);
xil_printf("%dEnd",YImage);
//从前64个数据里之后,图像数据从第1079开始,-54是因为前面已经读取了54个数据了
//这里的1078是直接手算的,并不是程序算的。
res = f_read(&fil,&line_buf[0],1078-54,&br);
xil_printf("BR%d",br);
int i;
f_read(&fil,frame,200*200,&br);
xil_printf("N%d K%d K%d,",br,frame[0],frame[200*200-1]);
xil_printf("Yes");
f_close(&fil);
}
int main()
{
init_platform();
int rc;
xil_printf("hello");
rc = SD_Init();
if(XST_SUCCESS != rc)
{
xil_printf("fail to init SD Card.");
}
else
{
xil_printf("success to init SD Card.");
}
u8 frameGet[200*200];
bmp_load("girl.bmp",&frameGet);
xil_printf("V%d V%d",frameGet[0],frameGet[200*200-1]);//输出两个像素点的值
cleanup_platform();
return 0;
}