跳轉到主要內容

色彩格式

色彩是顯示器的像素呈現出的樣子。 這些色彩來自影像緩衝區的值。 傳統上,繪圖系統中能夠表現、使用和顯示的色彩數量是有限的。 這同樣適用於TouchGFX的應用。

像素色彩的數量會影響到應用的許多方面。 從顯示器上所看到的內容的視覺外觀到影像緩衝產生的記憶體消耗,以及整體性能。 本節將進一步介紹TouchGFX中的色彩和可用的色彩格式,並指出其優缺點。

色彩

TouchGFX中的色彩是紅、綠和藍分量的三元組,即RGB色彩。 每個色彩分量的範圍為0至255。 0表示該分量無作用,255表示該分量處於最大值。

全黑色表示為RGB (0,0,0),全白色表示為 (255,255,255)。 亮綠色為 (0,255,0),半亮紅為 (128,0,0),暗紫色為 (64,0,64),以此類推。

一些RGB色彩

灰度

灰度應用的所有色彩均為灰色,包括從黑色到白色之間的所有灰色,因此用灰色強度(而不是RGB值)表示。 可將灰度色彩理解為R = G = B的RGB色彩。

不透明度

在某些情況下,我們會考慮為色彩增加一個描述色彩透明度的分量。 與色彩的其他分量一樣,不透明度的範圍為0至255。 有不透明度的色彩稱為RGBA色彩。 A表示alpha,是不透明度使用的傳統名稱。

完全不透明的黑色表示為 (0,0,0,255),有一些透明的紅色表示為 (255,0,0,128),諸如此類。

白色和灰色之上的一些RGBA色彩

當色彩並非完全不透明時,需將它與已存在的色彩進行混合。 這種色彩混合稱為Alpha混合。

色深

色深是指影像緩衝區中用於描述每種色彩的位元數。 我們將該值表示為每一像素位元數,或簡稱bpp。

使用的位元數越多,可描述的色彩越多。

常用的色深為24 bpp。 由於每一位元都可以是有或無,這表示可以呈現224 = 16777216種不同色彩。

另一個較少使用的色深是1 bpp。 此色深適用于黑白應用,只能呈現21 = 2種不同色彩。

TouchGFX支援下列色深:

  • 32 bpp - 16777216種色彩及相應的不透明度
  • 24 bpp - 16777216種色彩
  • 16 bpp - 65536種色彩
  • 6/8 bpp - 64種色彩
  • 4 bpp - 16種灰度色彩
  • 2 bpp - 4種灰度色彩
  • 1 bpp - 2種灰度色彩

關於色彩分量範圍的一些補充。 當使用的色深小於24 bpp時,紅、綠和藍分量中每一個的範圍並不直接取0至255。 以16 bpp的紅色分量為例,範圍為0至31。 我們將值31視為16 bpp色深時能夠表現的最紅的色彩,即24 bpp色深時的值255。 一種理解方式是16 bpp色深的色彩只是24 bpp色深可表現色彩的一個子集。

在6/8 bpp色深中,每個像素使用6位元表示色彩資訊(紅色、綠色和藍色各自以2個位元表示)。 為了簡化影像緩衝區的存取,每個像素從6位元增加至8位元(1位元組)。 影像緩衝區中多餘的兩位未使用。

格式

在確定表示色彩所需的位元數後,我們進一步探討位元的內容。 色彩通過位元來描述紅像素色、綠色和藍色,但色深本身並不能指定像素中位元的順序(格式)。 例如: 先是藍色,再是綠色,接著是紅,或者順序相反。

像素色彩格式

根據應用的色深,可使用某些特定的色彩格式。

RGB888

在TouchGFX中,色深為24 bpp的色彩其色彩格式為RGB888。 這意味著對紅、綠和藍分量中的每一個分量使用8個位元。

以亮紫色RGB (255,0,255) 為例,通過將分量組合成一個色彩值來表示這種色彩

uint32_t brightPurpleRGB888 = 255 << 16 | 0 << 8 | 255 << 0;

在這種格式中,紅色位於最高的8位,然後是綠色,藍色位於最低的8位。

RGB565

TouchGFX對16 bpp色彩使用色彩格式RGB565, 即紅、綠和藍色分別為5位、6位和5位。 由於紅色有5位,最亮為31,因此程式碼中的亮紫色為uint16_t brightPurpleRGB565=31<<11|0<<5|31<<0;

uint16_t brightPurpleRGB565 = 31 << 11 | 0 << 5 | 31 << 0;

RGBx2222, xRGB2222, BGRx2222, xBGR2222

對於6 bpp色彩,TouchGFX支援4種不同色彩格式:RGBx2222、xRGB2222、BGRx2222和xBGR222。 前述格式中之所以有x,是因為6位元色彩按位元組的形式存儲。 為了構成位元組,用2個位元填充色彩。 同時提供RGB和BGR是考慮到一些顯示器的需求,如此則無需在向顯示器發送像素前轉換像素。 在RGBx2222模式下,表示亮黃色的程式碼如下:

uint8_t brightYellowRGBx2222 = 3 << 6 | 3 << 4 | 0 << 2;

GRAY4, GRAY2, BW

對於每種灰度色深,TouchGFX都支援一種對應色彩格式。 4 bpp的色彩格式表示為GRAY4,2 bpp為GRAY2,1 bpp為BW(表示黑色和白色)。 對於4 bpp,全白色為

uint8_t whiteGRAY4 = 15;

TouchGFX有一項輔助工具,可返回色彩在當前色彩格式下的正確表示方法。

#include <touchgfx/Color.hpp>
...
aColor = Color::getColorFromRGB(255,0,128);

影像格式

影像是大多數UI應用的重要部分,影像由色彩填充而成。 在TouchGFX中,影像存儲在記憶體中,由特定格式的色彩填充而成。 在許多情況下,影像使用支援的像素色彩格式中的一種,但也可以使用其他影像格式。 在繪製前,特定影像色彩格式下的影像中的像素會被轉換為合適的像素格式

影像色彩格式描述
ARGB888832位,每個分量8位
L8_ARGB88888位元索引格式,ARGB8888調色板
RGB88824位,每個分量8位。
L8_RGB8888位元索引格式,RGB888調色板
RGB66624位,每個分量6位
RGB56516位,紅色5位、綠色6位和藍色5位
L8_RGB5658位元索引格式,RGB565調色板
ARGB22228位,每個分量2位
ABGR22228位,每個分量2位
RGBA22228位,每個分量2位
BGRA22228位,每個分量2位
GRAY44位灰度
GRAY22位灰度
BW1位灰度
BW_RLE1位元灰度運行長度編碼

這些影像格式中的一些格式(L8)按照色彩查閱資料表(稱為CLUT)來呈現相關影像並編入到該表中。 L8影像中色彩數量的最大可能值為28 = 256。 L8格式佔用的空間比非L8格式少,以包含200種不同色彩的100x100圖像為例,存儲為ARGB8888格式時的空間占用量為100x100x32位元 = 40000位元組,存儲為L8_ARGB8888格式時為100x100x8位元 + 200x32位元 = 10800位元組。 點選連結閱讀關於調色板圖像格式的更多內容:.

圖像格式BW_RLE按連續的黑色和白色存儲色彩,而不是存儲單一像素色彩。 在許多情況下,這種格式也可以更高效地利用存儲空間。

其餘格式與以上像素色彩格式相同。

影像緩衝區格式

並非所有圖像格式都可用作影像緩衝區格式。 L8格式不能用作TouchGFX中的影像緩衝區格式。 因為無法在影像緩衝區中混合兩個圖像。

位元組和像素順序

通常使用位元組指標存取24位元格式RGB888和32位格式ARGB888。 此時,須瞭解像素以低字節序(little endian) 存儲。

以32位色0xFFFF7700為例(alpha=0xFF,紅色=0xFF,綠色=0x77,藍色=0x00)。 當色彩位於32位元變數或暫存器中時,值為0xFFFF7700。 當色彩存儲在記憶體中時,存儲的位元組為{0x00、0x77、0xFF、0xFF}。 這與BGRA順序對應。

同樣,16位格式RGB565始終通過16位元指標存取,因此位元組順序並不重要,但會在記憶體中交換。

對於8位格式,例如:ARGB2222,該色彩適合一個位元組(兩個最高位元中的alpha),位元組存儲不變。

較小格式GRAY4、GRAY2和BW可按兩種順序存儲。 低位元可以是最左邊的像素或最右邊的像素。 如果低位元是最左邊的像素,我們稱之為LSB模式,反之則為MSB模式。

影像緩衝區格式順序描述
ARGB8888BGRA32位,每個分量8位
XRGB8888BGRX32位元,每個元件8位元,忽略alpha位元組
RGB888BGR24位,每個分量8位。
RGB56516位,紅色5位、綠色6位和藍色5位
ARGB22228位,每個分量2位
ABGR22228位,每個分量2位
RGBA22228位,每個分量2位
BGRA22228位,每個分量2位
GRAY4LSB4位灰度
GRAY2LSB2位灰度
BWMSB1位灰度

文字格式

文字,更準確地說是字形,也以特定色彩格式存儲在記憶體中。 TouchGFX中可供使用的文字色彩格式為

文字色彩格式描述
A88位,僅不透明度
A44位,僅不透明度
A22位,僅不透明度
A11位,僅不透明度

字形格式猶如小幅影像,每個色彩條目都儲存了每個像素的不透明度。 因此,日後不僅能應用實際色彩以及紅、綠和藍分量,還能繪製如儲存字形“A”的藍色和紅色版本。

每個字形使用的位元數越多,通常就會顯得越平滑和美觀。

視覺品質

對於嵌入式圖形,我們希望獲得最高視覺品質,但同時也需考慮記憶體的消耗量。

因此,通常趨向於使用RGB565色彩格式,而不是記憶體消耗量更大的RGB888色彩格式,一般而言,應在考慮存儲需求的同時選擇視覺品質最高的色彩格式。

抖動

在不同色彩格式下呈現圖像時,TouchGFX使用抖動技術來改善圖像的視覺品質。

抖動是一項廣為人知的技術,它讓圖像的色彩看起來比實際色彩更豐富。 這是通過增加圖像色彩的雜訊來實現的。

例如,在將RGB888圖像轉換為RGB565圖像時,並不試單純的將各個分量的數值減小,而是在轉換過程中為每個色彩分量添加一些雜訊,從而使轉換後的圖像看起來與原始RGB888圖像相似但更豐富。

下面用圖像而不是語言來表示,我們有一張原始RGB888圖像和許多轉換後的圖像。 轉換後的有和沒有抖動的RGB565格式圖像、xRGB2222格式圖像和GRAY4格式圖像。

原始RGB888圖像

轉換後的有和沒有抖動的RGB565圖像

轉換後的有和沒有抖動的xRGB2222圖像

轉換後的有和沒有抖動的GRAY4圖像

由此可見,抖動可顯著改善圖像的感知品質。 在近距離觀察有和沒有抖動的RGB565圖像時,可以看到有抖動的圖像與原圖像幾乎完全相似,而沒有抖動的圖像的一些區域則存在明顯的色帶。 這顯示在許多情況下,16位元色彩足以獲得看起來不錯的圖形。

如果圖形資產有巨大的色度斜率,即使在使用了抖動的圖像中,也會看到一些色帶。 下面是兩個範例。 從RGB888 (64,190,222) 到黑色的帶藍色的漸層及轉換後的有和沒有使用抖動的RGB565圖像。

原始RGB888和轉換後的有和沒有使用抖動的RGB565圖像

另一幅從 (255,0,0) 到黑色的紅色漸層。

原始RGB888和轉換後的有和沒有使用抖動的RGB565圖像

近距離觀察可以發現,有抖動和無抖動的RGB565圖像中均存在色帶。 紅色圖像中的色帶最為明顯。

務必密切注意所得圖像和色彩格式,必要時修改原始圖像或選擇其他色彩格式。

性能

討論的所有圖像格式均針對繪製的“容易性”進行了優化。 這意味著可以將圖像或多或少地複製到影像緩衝,無需進行大量轉換。

這是有意為之,是TouchGFX能夠在微控制器上獲得流暢圖形的原因之一。

在用TouchGFX設計UI時可使用.png圖像,在編譯時,會將每一幅圖像轉換為上述高效的圖像格式中的一種。

Alpha 混合

在執行時間,圖像資料的複製是通過常規CPU複製操作或使用MCU特性來完成的。 如果圖像包含不完全透明或不透明的像素,則需要用alpha混合技術將像素混合到背景上。 在一些STM32 MCU中,由硬體為這種混合提供支援。

其他圖像格式

如需在執行時間支援其他圖像格式,如壓縮圖像格式.jpg或.png,可以利用TouchGFX對動態點陣圖的支援。

Further reading
關於色深的Wikipedia文章。