動態點陣圖
本節介紹如何使用動態點陣圖。 注意,標準點陣圖會被編譯到應用中,因此必須在編譯時提供。 點陣圖從PNG等格式的檔案轉換而來,與大小和格式資訊一起以內部格式保存。
此外,還可以在執行時間在RAM中創建點陣圖。 這被稱為動態點陣圖。 動態點陣圖的使用與編譯到應用中的靜態點陣圖相同。 這意味著您可以通過圖像和按鈕等小部件使用動態點陣圖。
動態點陣圖配置
在創建動態點陣圖時,從點陣圖快取分配像素存儲空間。 因此,您必須先配置點陣圖快取,然後才能創建動態點陣圖。 This is a manual process that cannot be done in TouchGFX Designer or the Generator.
參見關於點陣圖快取的文章獲取配置說明。
必須定義應用中使用的動態點陣圖的最大數量。 該最大值與點陣圖快取位址和大小一起傳遞到TouchGFX。 這裡我們配置的是具有最多4張動態點陣圖的點陣圖快取。 您可以在應用中的任何檔中執行。 如需只執行一次,檔FrontendApplication.cpp是個不錯的選擇:
FrontendApplication.cpp (extract)
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/Bitmap.hpp>
FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
: FrontendApplicationBase(m, heap)
{
// Place cache start address in SDRAM at address 0xC0008000;
uint16_t* const cacheStartAddr = (uint16_t*)0xC0008000;
const uint32_t cacheSize = 0x300000; //3 MB, as example
Bitmap::setCache(cacheStartAddr, cacheSize, 4);
}
如果您使用Windows模擬器,則還必須在此創建點陣圖快取。 在Windows上,可以容易地宣告大陣列或使用malloc:
FrontendApplication.cpp (extract)
#include <gui/common/FrontendApplication.hpp>
#include <touchgfx/Bitmap.hpp>
FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
: FrontendApplicationBase(m, heap)
{
#ifdef SIMULATOR
const uint32_t cacheSize = 0x300000; //3 MB, as example
uint16_t* const cacheStartAddr = (uint16_t*)malloc(cacheSize);
Bitmap::setCache(cacheStartAddr, cacheSize, 4);
#else
// Place cache start address in SDRAM at address 0xC0008000;
uint16_t* const cacheStartAddr = (uint16_t*)0xC0008000;
const uint32_t cacheSize = 0x300000; //3 MB, as example
Bitmap::setCache(cacheStartAddr, cacheSize, 4);
#endif
}
使用動態點陣圖範例
為了使用動態點陣圖,我們需要一個小部件來顯示它。 So insert an Image widget in the view (in code or in TouchGFX Designer):
#include <touchgfx/widgets/Image.hpp>
using namespace touchgfx;
class TemplateView : public View
{
private:
Image image;
}
此小部件和動態點陣圖的使用過程分為三步:
- 在點陣圖快取中創建動態點陣圖
- 清空動態點陣圖使用的存儲空間
- 將點陣圖分配給小部件
在setupScreen中創建動態點陣圖。 這裡我們使用16bpp格式RGB565。 如果影像緩衝為24位,則使用RGB888。 如需創建透明點陣圖,使用格式ARGB8888。
通過dynamicBitmapGetAddress函數返回動態點陣圖中像素的位址:
#include <touchgfx/Bitmap.hpp>
void TemplateView::setupScreen()
{
BitmapId bmpId;
//Create (16bit) dynamic bitmap of size 100x150
const int width = 100;
const int height = 150;
bmpId = Bitmap::dynamicBitmapCreate(100, 150, Bitmap::RGB565);
//set all pixels white
if (bmpId != BITMAP_INVALID)
{
memset(Bitmap::dynamicBitmapGetAddress(bmpId), 0xFF, width*height*2);
}
//Make Image widget show the dynamic bitmap
image.setBitmap(Bitmap(bmpId));
//Position image and add to View
image.setXY(20, 20);
add(image);
...
}
您從點陣圖快取獲得的像素存儲空間未清空,建議立即將其清空或重寫。
如需從檔案載入圖像,可以用載入器程式碼替代對memset的呼叫。 參見文章在執行時間載入圖像
動態點陣圖操作
動態點陣圖操作全部位於Bitmap類中。
創建動態點陣圖
以下方法用指定的寬度、高度和點陣圖格式創建動態點陣圖。 僅當有足夠大的未使用存儲空間時,才能創建點陣圖。 如果未創建點陣圖,該方法返回BITMAP_INVALID。
static BitmapId Bitmap::dynamicBitmapCreate(const uint16_t width, const uint16_t height, BitmapFormat format, ClutFormat clutFormat)
刪除動態點陣圖
此方法刪除動態點陣圖。
static bool Bitmap::dynamicBitmapDelete(BitmapId id)
獲取動態點陣圖中像素的位址
以下方法返回動態點陣圖的位址。 檔案載入器使用此方法將圖像資料複製到點陣圖中。
static uint8_t* dynamicBitmapGetAddress(BitmapId id)
設置動態點陣圖的實心區域
以下方法設置動態點陣圖的實心矩形。
static bool dynamicBitmapSetSolidRect(BitmapId id, const Rect& solidRect)
請閱讀Custom Widget一節中關於“實心區域”概念的更多內容。
對於像RGB565和RGB888這樣的非透明格式,將實心區域預設設置為整個點陣圖。 對於像ARGB8888這樣的透明格式,將實心區域設置為空。
Creating a Dynamic Bitmap from memory
It is also possible to create a dynamic bitmap directly from pixel data in flash memory without caching pixel data in RAM. Compared to regular Dynamic Bitmap, cache size does not need to take into account the pixel data:
Note that the pixel address must be 4-byte aligned.
static BitmapId Bitmap::dynamicBitmapCreateExternal(const uint16_t width, const uint16_t height, const void* pixels, BitmapFormat format, uint8_t customSubformat = 0);
豎屏模式的動態點陣圖
TouchGFX能以豎屏模式運行。 這適用於顯示器自其原始方向旋轉90度後安裝的情況。 在該模式下使用動態點陣圖時,需要格外小心。
下面是STM32F746的專案範例。 它的顯示器寬度為480像素,高度為272像素。 影像緩衝具有相同大小。
沒有為image1圖像小部件分配點陣圖。 我們將使用它顯示動態點陣圖。
在使用豎屏模式時,坐標系統沿逆時針方向旋轉90度。 (0, 0) 座標位於“D”附近的左上角。 影像緩衝的第一個位元組(將螢幕上第一個像素著色),位於右上角。
因此,當以豎屏模式運行時,不旋轉影像緩衝。 對於動態點陣圖也是如此。 但是我們希望在顯示器(安裝時)第一行顯示的像素必須繪製在影像緩衝區的左邊緣。
在下面的函數中創建動態點陣圖,使上面一行為綠色且右邊緣為紅色:
Screen1View.cpp (extract)
void Screen1View::setupScreen()
{
Screen1ViewBase::setupScreen();
BitmapId bmpId;
bmpId = Bitmap::dynamicBitmapCreate(100, 100, Bitmap::RGB565);
if (bmpId != BITMAP_INVALID)
{
//set all pixels white
uint16_t* const bitmapPixels = (uint16_t*)Bitmap::dynamicBitmapGetAddress(bmpId);
memset(bitmapPixels, 0xFF, 100*100*2);
//first 200 pixels red, => two column on the right on display
for (int i = 0; i<200; i++) bitmapPixels[i] = 0xF800;
//first two pixels in all rows green in bitmap => top two rows on display
for (int i = 0; i<100; i++)
{
bitmapPixels[i*100] = 0x07E0;
bitmapPixels[i*100 + 1] = 0x07E0;
}
}
image1.setBitmap(bmpId);
}
顯示器顯示動態點陣圖: