上一次講到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 <stdio.h>
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;
}