Android 的 Color.RGBToHSV 方法會將 8 位元的紅、綠、藍三元組轉換為 HSV 三元組,其中色相以度數表示,範圍為半開放區間 [0, 360),飽和度位於封閉區間 [0, 1],明度也位於 [0, 1],之後才會在 UI 層級轉換為百分比。介面簽章為 public static void RGBToHSV(int r, int g, int b, float[] hsv),而 Android Color 參考文件 明確指出 hsv[0] 為色相 ([0..360[)、hsv[1] 為飽和度 ([0...1]),hsv[2] 為明度 ([0...1])。由於飽和度與明度是以原始小數形式傳回,當工具顯示 50% 飽和度時,它實際上回報的是浮點數 0.5,而非整數 50。任何遵循與 Color.RGBToHSV 相同慣例的轉換器,都能讓結果直接套用至 Android 色彩管線、Jetpack Compose 的 Color.hsv(...) 建構函式,或任何預期使用平台所記載比例尺度,而非臨時百分比機制的圖形常式。

Android 對 RGB 轉 HSV 結果的實際要求
Android 圖形框架定義了兩個相關的輔助函式。Color.RGBToHSV(int r, int g, int b, float[] hsv) 接受分離的整數色通道,而 Color.colorToHSV(int color, float[] hsv) 接受一個封裝的 ARGB 整數,其中 alpha 位元組在轉換過程中會被捨棄。這兩個輔助函式都會填入所提供的 float 陣列,索引 0 為以度數表示的色相、索引 1 為飽和度、索引 2 為明度,且兩者皆遵循相同的記載範圍,因此應用程式可以使用相同的下游邏輯處理任一種輸入形式。色相以包含 0 但排除 360 的半開放區間回報,這表示 359.99 與 0.01 在色輪上是刻意不同的點,而剛好等於 360.0 的結果則絕不會出現。
Android 開發者將數值從此陣列移入程式碼時,通常會重新調整小數比例。Compose 的 Color.hsv(20f, 0.75f, 0.78f, 1f) 呼叫會完全對應這些小數;而透過 Color.HSVToColor(0xff, hsv) 設定 Canvas Paint 顏色的做法,則是將同一個陣列傳回框架進行反向運算,並回傳適合 setColor 使用的封裝 ARGB 整數。以瀏覽器為基礎的 RGB 轉 HSV 轉換器 為了易讀性會顯示百分比,但其底層 JavaScript 數值與 Android 計算的數值相同,因此讀者可以直接將顯示的百分比除以 100,並在不需要重新調整色相,也不需要重新調整整個陣列的情況下,直接傳入 Color.HSVToColor。
用三個步驟為 Android 將 RGB 轉換為 HSV
- 在轉換器的輸入欄位中輸入介於 0 到 255 之間的整數紅、綠、藍色通道值。該工具會明確拒絕小數、空值、負數,以及任何超過 255 的值並顯示錯誤訊息,如此一來,打錯字就不會在下游變成一個看似合理但實際錯誤的顏色。
- 選擇「轉換為 HSV」動作,並讀取半開放區間 [0..360[ 內的色相、以百分比表示的飽和度,以及以百分比表示的明度。即時色塊可驗證對色塊來源顏色,同時正規化後的 HSV 數值與來源 HEX 色碼也會一併顯示,方便複製貼上。
- 在將結果貼回 Color.HSVToColor 或 Compose 的 Color.hsv(...) 呼叫之前,先將結果轉譯回 Android 的 float 陣列。色相需完全以度數保留顯示數值,並將兩個百分比都除以 100,使 75.00% 變成飽和度 0.75f、78.43% 變成明度 0.7843f。
在 Android 尺度上讀取結果
在實務中會出現三種不同的 HSV 輸出尺度,選錯尺度正是「正確」的轉換在 Android 上表現不如預期最常見的原因。下表顯示轉換器顯示結果、Android API,以及部分第三方函式庫所使用的精簡影像處理範圍之間的精確對應關係。
| 元件 | 轉換器顯示 | Android Color.RGBToHSV | 精簡影像範圍 |
|---|---|---|---|
| 色相 | 度數,0.00 到 359.99 | 度數,[0..360[ | 整數,0 到 179 (OpenCV H/2) 或 0 到 255 |
| 飽和度 | 百分比,0.00 到 100.00 | 浮點數,0.0 到 1.0 | 整數,0 到 255 |
| 明度 | 百分比,0.00 到 100.00 | 浮點數,0.0 到 1.0 | 整數,0 到 255 |
半開放的色相區間是讓新手感到意外的細節。Android 的 [0..360[ 標記法代表 360 永遠不會被回傳;框架會將該角度折返為 0,因為紅色同時位於循環的起點與終點。任何外部函式庫若回報色相為 360.0,即代表其使用的是與平台不同的封閉區間慣例,這也正是轉換器刻意將顯示值上限壓在 360 以下,以維持與 Color.RGBToHSV 相容性的原因。當數值透過 Color.HSVToColor 反向回傳時,同樣的嚴謹態度也很重要:平台方法會將超出記載範圍的輸入進行截斷,而不是回報錯誤,因此手動重新調整比例可讓呼叫保持在文件所記載的合約範圍內。
在程式碼中對齊 Color.RGBToHSV 方法
對於想在實際裝置上確認瀏覽器結果與平台方法相符的讀者,以下 Java 程式序列執行的是相同的計算:float[] hsv = new float[3]; Color.RGBToHSV(200, 100, 50, hsv); 會將 hsv[0] 填入 20.0、hsv[1] 填入 0.75、hsv[2] 填入約 0.7843。動手運算這些數字即可明白結果為何會精準落在轉換器所回報的位置。
在 R = 200、G = 100、B = 50 的情況下,各通道皆除以 255,因此正規化後的通道值為 0.7843、0.3922 和 0.1961。最大通道為紅色,因此 V = 0.7843。最大值與最小值之間的差值為 0.7843 − 0.1961 = 0.5882,而飽和度為差值除以最大值,即 0.5882 / 0.7843 = 0.75。由於紅色為最大通道,色相計算方式為 ((G − B) / delta) × 60,代入後為 ((0.3922 − 0.1961) / 0.5882) × 60 = 0.3333 × 60 = 20°。因此轉換器會顯示色相 20.00°、飽和度 75.00%、明度 78.43%,而平台方法會以完整浮點精度將陣列填入 {20.0, 0.75, 0.7843137}。此實作已根據典型的 0–255 sRGB 輸入,獨立對照 R 的 grDevices rgb2hsv 慣例進行驗證,因此相同的數字也會出現在瀏覽器、裝置以及統計繪圖工具中。
Android 360 度色輪上的色相錨點
在色相圓上有六個純色位於固定角度,當需要快速檢查轉換是否正確時,它們是實用的參考點。下表列出 Android Color 參考文件與轉換器黃金測試集中皆會出現的標準錨點。
| 錨點顏色 | 色相 (度數) | RGB 範例 |
|---|---|---|
| 紅色 | 0 | 255, 0, 0 |
| 黃色 | 60 | 255, 255, 0 |
| 綠色 | 120 | 0, 255, 0 |
| 青色 | 180 | 0, 255, 255 |
| 藍色 | 240 | 0, 0, 255 |
| 洋紅色 | 300 | 255, 0, 255 |
由於色輪的幾何在各實作之間是共通的,因此這些位置在 Android、CSS、轉換器,以及大多數繪圖函式庫之間並不會改變。會改變的是各函式庫之間的飽和度與明度尺度,這也正是為何平台的 [0, 1] 慣例值得牢記,才能在百分比與程式碼之間混用時不出錯。對於想要一頁即可列印的完整錨點參考的讀者,帶有範例色塊的色輪視覺摘要也已彙整於專屬的 RGB 轉 HSV 色輪參考 頁面中。
常見邊緣情況與 Android 的處理方式
有三種輸入會產生看起來很奇怪、直到理解其慣例後才會明瞭的結果。首先,當紅、綠、藍三色相等時,該三元組位於灰階軸上,因此差值為零、飽和度為零,且色相在視覺上沒有意義;Android 會回傳佔位色相 0,轉換器同樣會顯示 0.00°。其次,當三個通道皆為零時,顏色為純黑色,明度為 0、飽和度為 0,實作會落入相同的非彩軸分支;Color.HSVToColor 會將其反轉為 0xFF000000。第三,轉換器的嚴格輸入驗證可攔截那些會向下游傳遞到 Android 的輸入錯誤:在其他工具中,值為 256 時會悄悄飽和為 255,最終會落在 Color.rgb(255, g, b) 上,看起來正確但其實是錯的,因此刻意拒絕超出範圍的整數是一種保護機制,而不是困擾。
在反向傳遞數值時,同樣的嚴謹態度也很重要。Color.HSVToColor 在飽和度與明度超出 [0, 1] 區間時會採取寬鬆處理,因此在飽和欄位中手動輸入 2.0 會悄悄變成 1.0,而負值的色相則會在毫無警示的情況下折返為正角度。從轉換器讀取百分比並除以 100,可讓輸入保持在記載範圍內,避免發生這種靜默截斷。轉換器也會顯示底層的正規化 HSV 表示法,而這正是 Android 陣列式方法所直接接受的格式。
在 Android 上 HSV 並非最佳工具的情境
HSV 適合在色彩選擇器中調整色相與亮度,但它既不是感知模型,也不是亮度模型。HSV 的明度分量是正規化後的最大 RGB 通道,而不是 HSL 中 L 所捕捉的感知亮度,更不是無障礙工具所測量的亮度。對於必須滿足無障礙比例的前景與背景組合,請將實際的 HEX 或 RGB 配對送入 色彩對比檢查工具 中檢驗,而不是從明度的高低來推測可讀性。對於寬色域影像描述檔,轉換器 8 位元 sRGB 的假設並不適用,此時需要具備描述檔感知能力的管線。轉換器最適合用於文件所記載的 Android 情境:將 8 位元 RGB 三元組精準轉換為 Color.RGBToHSV 所回傳的色相、飽和度與明度尺度。
若想進一步了解,請參閱 CIEDE2000 計算機能否證明兩個印刷樣本相符?。