ノロノロとではありますが、FT800の実験を続けています。きょうのお題はJPEGファイルの表示です。
FT800には、JPEGの展開機能が用意されています。CMD_IMAGELOADコマンドに続いてJPEGファイルのデータを送ってやると、これを指定したFT800のGraphics RAM(RAM_G)メモリ領域のアドレス移行に展開してくれます。展開した結果は、RGB565のビットマップやモノクロのビットマップ形式として変換することができます。
試しに、FTDIのサイトから拾ったEVE姐さんの画像を表示してみました。元の画像データは496×351ドットだったので、この縦横比を保って384×272ドットの大きさに変換したJPEGファイルを用意しました。このファイルをボード上のSPIフラッシュ上に書き込んでおき、これをFatFsで読み込んで表示しています。実際のコードはこんな感じです。概要を示すために、細かなエラーチェックは省略しています。
RGB565に展開されたビットマップ画像は、BEGIN(BITMAPS)/ENDで囲まれたVERTEX2IIで指定される座標に表示されます。表示するには、ビットマップ画像の大きさやレイアウト情報が必要となるので、それをBITMAP_LAYOUTとBITMAP_SIZEで与えています。BITMAP_SIZEでは縦横384×272ドットの画像であることを示しています。この画像はRGB565形式であるため1画素あたり2バイトが必要です。そのため、メモリ上でのレイアウトとしてはX方向には384×2バイトの領域が必要となります。BITMAP_LAYOUTではこの情報を渡しているわけです。この例では画像のサイズは既知であるので、定数として埋め込んでいますが、実際にはJPEG画像のヘッダー部分をデコードしてサイズを求めた方が一般性のあるコードとなります。
RAM_Gの領域サイズは256kBとなっているので、展開結果のビットマップサイズが、これを超える画像は扱うことができません。RGB565形式では一画素あたり2バイトを必要としますので、480×272ドットの画像がギリギリで表示できることになります。そのため、デジカメで撮影したデータを表示するフォトフレームのようなアプリを直接実現することはできません。今時のデジカメは、最小撮影サイズでも640×480ドットはありますので、あらかじめ縮小しておくことが必要となってしまいます。このような制限があるものの、画像データを圧縮して持てるので、フラッシュ容量の大きいマイコンを使用すれば、かなりの枚数の画像を保持することも可能となります。
FT800には、JPEGの展開機能が用意されています。CMD_IMAGELOADコマンドに続いてJPEGファイルのデータを送ってやると、これを指定したFT800のGraphics RAM(RAM_G)メモリ領域のアドレス移行に展開してくれます。展開した結果は、RGB565のビットマップやモノクロのビットマップ形式として変換することができます。
試しに、FTDIのサイトから拾ったEVE姐さんの画像を表示してみました。元の画像データは496×351ドットだったので、この縦横比を保って384×272ドットの大きさに変換したJPEGファイルを用意しました。このファイルをボード上のSPIフラッシュ上に書き込んでおき、これをFatFsで読み込んで表示しています。実際のコードはこんな感じです。概要を示すために、細かなエラーチェックは省略しています。
FATFS fatfs; FIL f_info; void do_Image(Ft_Gpu_Hal_Context_t *phost) { FRESULT res; int nb, eof; res = f_mount(0, &fatfs); res = f_open(&f_info, "/PReve1.jpg", FA_READ); /* Load JPEG image into RAM_G space */ Ft_Gpu_Hal_WrCmd32(phost, CMD_LOADIMAGE); Ft_Gpu_Hal_WrCmd32(phost, RAM_G); /* Destination address of jpg decode */ Ft_Gpu_Hal_WrCmd32(phost, 0); /* output format */ eof = 0; while (!eof) { res = f_read(&f_info, (void*)image_buffer, sizeof(image_buffer), &nb); if (res != FR_OK || nb ≤ 0) eof = 1; else Ft_Gpu_Hal_WrCmdBuf(phost, image_buffer, nb); } f_close(&f_info); Ft_Gpu_CoCmd_Dlstart(phost); Ft_App_WrCoCmd_Buffer(phost, CLEAR_COLOR_RGB(0xc0,0xc0,0xc0)); /* background */ Ft_App_WrCoCmd_Buffer(phost, CLEAR(1,1,1)); Ft_App_WrCoCmd_Buffer(phost, COLOR_RGB(255,255,255)); Ft_App_WrCoCmd_Buffer(phost, BITMAP_SOURCE(RAM_G)); /* Source bitmap size is 384x272 */ Ft_App_WrCoCmd_Buffer(phost, BITMAP_LAYOUT(RGB565,384*2,272)); Ft_App_WrCoCmd_Buffer(phost, BITMAP_SIZE(BILINEAR,BORDER,BORDER,384,272)); Ft_App_WrCoCmd_Buffer(phost, BEGIN(BITMAPS)); Ft_App_WrCoCmd_Buffer(phost, VERTEX2II(0,0,0,0)); Ft_App_WrCoCmd_Buffer(phost, END()); Ft_App_WrCoCmd_Buffer(phost, DISPLAY()); Ft_Gpu_CoCmd_Swap(phost); /* Download the commands into fifo */ Ft_App_Flush_Co_Buffer(phost); }
RGB565に展開されたビットマップ画像は、BEGIN(BITMAPS)/ENDで囲まれたVERTEX2IIで指定される座標に表示されます。表示するには、ビットマップ画像の大きさやレイアウト情報が必要となるので、それをBITMAP_LAYOUTとBITMAP_SIZEで与えています。BITMAP_SIZEでは縦横384×272ドットの画像であることを示しています。この画像はRGB565形式であるため1画素あたり2バイトが必要です。そのため、メモリ上でのレイアウトとしてはX方向には384×2バイトの領域が必要となります。BITMAP_LAYOUTではこの情報を渡しているわけです。この例では画像のサイズは既知であるので、定数として埋め込んでいますが、実際にはJPEG画像のヘッダー部分をデコードしてサイズを求めた方が一般性のあるコードとなります。
RAM_Gの領域サイズは256kBとなっているので、展開結果のビットマップサイズが、これを超える画像は扱うことができません。RGB565形式では一画素あたり2バイトを必要としますので、480×272ドットの画像がギリギリで表示できることになります。そのため、デジカメで撮影したデータを表示するフォトフレームのようなアプリを直接実現することはできません。今時のデジカメは、最小撮影サイズでも640×480ドットはありますので、あらかじめ縮小しておくことが必要となってしまいます。このような制限があるものの、画像データを圧縮して持てるので、フラッシュ容量の大きいマイコンを使用すれば、かなりの枚数の画像を保持することも可能となります。