RGB (紅、綠、藍) 將任何 8 位元數位色彩描述為三個範圍介於 0 到 255 之間的整數通道,而 HSV (色相、飽和度、明度) 則以 360 度色環上的色相角度加上飽和度與明度百分比,重新描述同一種色彩。兩者並非不同的色彩空間 —— 它們是同一個像素的兩套座標系統。

單一 HSV 輸出必定包含三個數字:一個介於 0° 到 360° 之間的色相 (紅色從 0° 開始,黃色為 60°,綠色為 120°,青色為 180°,藍色為 240°,洋紅為 300°)、一個飽和度 (以百分比表示,色彩越遠離灰色其值越大),以及一個明度 (以百分比表示,等於最大標準化通道)。對於純色通道,結果是固定的:(255, 0, 0) 必定轉換為 HSV(0°, 100%, 100%),而 (0, 255, 0) 則轉換為 HSV(120°, 100%, 100%)。貫穿所有範例的共同規則是:明度追蹤最強的通道,而色相則追蹤哪個通道最強以及另外兩個通道向它靠近的程度。

rgb to hsv examples
RGB 轉 HSV 範例:常見色彩的實際轉換結果

RGB 與 HSV 所代表的意義

RGB 以紅、綠、藍光線相加的量來描述色彩,在標準的 8 位元數位作業中,每個通道以 0 到 255 之間的整數儲存。HSV 則圍繞三項通常更易於操作的屬性重新組織同一個三元組:360° 色環上的色相角度、描述色彩距離灰色多遠的飽和度百分比,以及等於三元組中最強通道的明度百分比。兩個色彩空間描述的是同一個像素 —— 差異純粹在於座標的安排方式。

HSV 在許多設計工具中也稱為 HSB (色相、飽和度、亮度),不過 HSV 的明度元件在技術上是 RGB 通道的最大值,而非感知上的亮度。兩者的關係純粹是數學上的:HSV 圍繞著通常更便於調整的屬性重新組織同一個三元組。透過範例實際演練是最快將其內化的方式,而且由於純色與灰色值會產生數學上固定的輸出,你可以不必每次都實際計算就能預測結果。RGB 轉 HSV 轉換器可處理任意輸入的運算,且僅接受 0 到 255 之間的整數通道。

色環上常見的 RGB 轉 HSV 範例

下表顯示將純原色與純二次色通道輸入轉換時會發生的結果,並列出幾個無彩色 (灰色軸) 的情況。這些並非單一樣本運算的結果 —— 它們是每種色彩在 HSV 色環上所在位置的數學定義。

RGB 輸入色彩色相 (°)飽和度 (%)明度 (%)
(255, 0, 0)純紅0100100
(255, 255, 0)黃色60100100
(0, 255, 0)純綠120100100
(0, 255, 255)青色180100100
(0, 0, 255)純藍240100100
(255, 0, 255)洋紅300100100
(0, 0, 0)黑色0 (預設值)00
(255, 255, 255)白色0 (預設值)0100
(128, 128, 128)中灰色0 (預設值)050.20

從表格中可以明顯看出兩個規律。第一,每個純原色與純二次色在色環上佔據固定的色相位置 —— 相鄰項目之間相隔 60° —— 並達到最大飽和度與明度。第二,當三個通道全部相等時,最大值與最小值之間的差為零,因此飽和度塌縮為零,色相在數學上變得未定義;轉換器會回報慣用的預設色相 0°。完整的演算法已獨立對照 R 語言 grDevices 的 rgb2hsv 慣例進行交叉驗證,因此表格中的數值與科學運算環境所產生的結果一致。

如何以三個步驟將 RGB 轉換為 HSV

  1. 將紅、綠、藍通道以 0 到 255 之間的整數輸入轉換器。小數值、空欄位、負數,以及任何超過 255 的數值會產生明確的錯誤,而非被靜默地四捨五入或限制。
  2. 選擇 Convert to HSV (轉換為 HSV)。該工具會將每個整數除以 255,找出最大與最小的通道,計算其差值,並根據哪個通道佔據主導套用標準的分段色相公式。
  3. 讀取以度數表示的色相 (0–360)、以百分比表示的飽和度,以及以百分比表示的明度。同一畫面也會顯示標準化的 HSV 表示法、來源 HEX 色碼,以及視覺色塊,方便你比較原始色彩與其 HSV 表示。
  4. 在複製結果之前,請先確認目的地端預期的是度數與百分比、0 到 1 的小數,或是例如 0–179 色相的精簡整數範圍。以 80.90% 表示的飽和度在 0 到 1 的尺度上等同於 0.809,而非整數 80。

RGB 轉 HSV 公式解析

這個轉換簡短到可以針對單一範例用手工方式完成。取輸入 R = 200、G = 100、B = 50 —— 一個非純色的暖橘色。

將每個通道除以 255 以進行標準化:

  • R' = 200 / 255 ≈ 0.7843
  • G' = 100 / 255 ≈ 0.3922
  • B' = 50 / 255 ≈ 0.1961

最大值為 R' (0.7843),最小值為 B' (0.1961),因此:

  • delta = max − min = 0.7843 − 0.1961 = 0.5882
  • value = max = 0.7843 → 78.43%
  • saturation = delta / max = 0.5882 / 0.7843 = 0.75 → 75%

由於紅色是最大的通道,色相公式變為 60° × (G' − B') / delta:

  • hue = 60 × (0.3922 − 0.1961) / 0.5882 = 60 × 0.3333 = 20°

完整轉換結果為 HSV(20°, 75%, 78.43%)。這正是 RGB 轉 HSV 轉換器所回報的數值。在內部,結果是一個未經四捨五入的 JavaScript 數字;僅在顯示時四捨五入至小數點兩位以利閱讀。

若最大值為綠色,公式會切換為 60° × (2 + (B' − R') / delta);若最大值為藍色,則會再次切換。出現負的中間結果時,會透過加上 360 來進行環繞,以使色相保持在標準的 0° 到 360° 範圍內 —— 這與 Android Color 說明文件所使用的慣例相同。

無彩色與色相預設值

無彩色是指三個通道全部相等的任何 RGB 三元組 —— 黑色、白色,以及介於兩者之間的每種灰色。在這些情況下,最大值與最小值之間的差為零,因此標準飽和度公式會發生除以零的狀況,而分段色相公式也沒有有意義的答案,因為沒有任何單一通道佔據主導。

此處採用的修正是慣用的做法:當色彩為無彩色時,轉換器會將飽和度回報為 0,並將色相設為預設值 0 度。色相數字仍會輸出,以便輸出資料列的格式永遠保持一致,但它並不帶有任何視覺資訊。若你打算將結果餵入期望真實色相的程式 (例如基於色相的動畫),辨識這個預設值就很重要 —— 此類程式會將 0° 視為紅色,除非你明確過濾掉無彩色的情況,否則會產生突然跳離灰色的效果。

這也是為什麼快速檢查飽和度欄位是判斷色相值是否有意義的最快方式。任何低於百分之一小數的值基本上都是無彩色,該資料列中的色相應該予以忽略。

符合你的軟體所預期的輸出尺度

不同的程式與影像處理函式庫以不同的尺度儲存 HSV,而這正是兩個轉換器對同一輸入看似結果不一致的最常見原因。

  • CSS 與許多設計工具使用度數與百分比。一個典型的 CSS 表示法看起來像 hsv(210, 88%, 100%) —— 這是轉換器預設顯示的形式。
  • 部分軟體 (包括 OpenCV 的某些部分) 使用 0–179 的色相範圍,以將色相位元組容納進 8 位元中。在其他處顯示為 210° 的同一色彩,在該尺度下會讀作 105。
  • 接受浮點色彩向量的數值 API 通常預期飽和度與明度在 0.0–1.0 範圍內,而非 0–100。請將顯示的百分比除以 100。
  • 精簡整數格式偶爾也會將飽和度與明度編碼為 0–255 尺度,尤其是在較舊的調色盤中。

轉換器所依循的參考資料之一 —— Android Color 說明文件 —— 將色相視為 0 ≤ H < 360,並將飽和度與明度視為 0.0–1.0 範圍內的浮點數,再以百分比顯示。若目的地端預期的是 HSL 而非 HSV,請勿將明度元件重新標示 —— 明度追蹤的是最大通道,而亮度則是最大與最小通道的平均值,兩者並不可互換。當目的地為 HSL 時,請使用專門的 HSL 轉換器。

超越色環的實際範例

一旦你超越六個純色環位置與灰色軸,轉換就成了單純的算術問題。然而,這段關係的型態遵循兩條簡單的規則。第一,任何具有單一主導通道且另外兩個通道接近零的色彩,會落在該通道色相附近,並達到接近 100% 的飽和度。第二,將其他通道拉向最大值會使飽和度下降,並將色相推向最後追上來的通道。從鮮豔橘色到低飽和棕褐色的微妙轉變保留了橘色色相帶,但會沿著灰色軸明顯地扁平化色彩,此時轉換器會顯示飽和度下降,而色相仍維持在同一個 30° 區域內。

對於任意輸入,最快的做法是將通道輸入 RGB 轉 HSV 轉換器並讀取數值。若要比較調色盤座標,或將 8 位元 RGB 樣本移入僅公開 HSV 的控制項,這個在瀏覽器中執行的工具完全在用戶端運行,且不會儲存色彩紀錄 —— 適用於設計探索、腳本撰寫與教學,而無需將資料傳送至任何地方。輸入內容在轉換後仍保持可見,因此修改單一通道並再次按下 Convert,是觀察三個 HSV 元件如何響應單一通道調整的快速方法。

若你在權衡選項,從影像中的 HEX 色碼轉換為 RGB 通道對此有詳細說明。

若你在權衡選項,CMYK 色表提示:命名色彩的常見錯誤對此有詳細說明。