js 顏色轉換分析

一、十六進制轉RGB

  function hexToRgba(hex) {// 移除 # 字符hex = hex.replace('#', '');// 處理簡寫形式如 #fffif (hex.length === 3) {hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];}// 轉換為十進制const r = parseInt(hex.substring(0, 2), 16); // 截圖前兩位,然后16進制轉為10進制const g = parseInt(hex.substring(2, 4), 16);const b = parseInt(hex.substring(4, 6), 16);return `rgb(${r}, ${g}, ${b})`;}
  • 使用十六進制表示顏色時,每兩位代表一個顏色通道(#RRGGBB:RR=紅,GG=綠,BB=藍),范圍00-FF(十進制0-255)。

二、RGB轉十六進制

function rgbToHex(rgbStr) {// 提取 RGB 值const match = rgbStr.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/i);if (!match) {throw new Error('Invalid RGB/RGBA string format');}// 解析顏色分量const r = parseInt(match[1]);const g = parseInt(match[2]);const b = parseInt(match[3]);// 轉換為十六進制const toHex = (num) => {const hex = Math.min(255, Math.max(0, num)).toString(16);return hex.length === 1 ? '0' + hex : hex;};return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}
  • 使用正則表達式匹配rgb/rgba
    /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)$/i // (?:,\s*([\d.]+))?:可選捕獲透明度部分
    
  • 數值范圍處理和十六進制轉換
    const toHex = (num) => {// 1. 確保顏色值在 0-255 范圍內// 2. 處理可能的非法輸入值// 3. 轉為十六進制const hex = Math.min(255, Math.max(0, num)).toString(16);return hex.length === 1 ? '0' + hex : hex;
    };
    

三、十六進制轉HSL

(一)、什么是HSL

HSL(Hue, Saturation, Lightness)是一種基于人類感知的顏色表示方法,廣泛應用于計算機圖形學、網頁設計和圖像處理等領域。它比傳統的 RGB(紅綠藍)模型更直觀,便于調整顏色的色調、鮮艷度和明暗。

(二)、HSL中H、S、L分別代表什么

H:色相(Hue, H)

  • 定義:顏色的基本類型(如紅、綠、藍)。
  • 范圍:0°–360°(環形色輪)。
    0° = 紅色
    120° = 綠色
    240° = 藍色
    360° = 回到紅色
    在這里插入圖片描述

色相和色度的區別

特性色相(Hue)色度(Chroma)
定義顏色的種類(紅、綠、藍等)顏色的純度(鮮艷程度)
幾何表示色輪上的角度(0°–360°)顏色點到灰度軸的距離
物理基礎光的波長顏色成分的純度(與灰度的偏離)
調整效果改變顏色類別(如紅→藍)改變顏色的鮮艷度(如鮮紅→灰紅)
感知獨立性與明度、飽和度無關與明度相關(明度影響最大色度)

S:飽和度(Saturation, S)

  • 定義:顏色的鮮艷程度(從灰度到純色)。
  • 范圍:0%–100%
    0% = 灰色(完全去色)
    100% = 最鮮艷的顏色
    在這里插入圖片描述

L:明度(Lightness, L)

  • 定義:顏色的明暗程度(從黑到白)。
  • 范圍:0%–100%
    0% = 純黑
    50% = 標準顏色
    100% = 純白

(三)、HSL的圓柱模型

HSL還有雙六棱錐模型,這里主要說圓柱模型
HSL(色相、飽和度、明度)的圓柱模型是一種直觀的幾何表示方式,將顏色的三個屬性映射到三維空間中。

基本結構

  • 色相(Hue, H)
    • 幾何位置:圍繞圓柱的圓周方向(0°–360°)。
    • 物理意義:顏色在色輪上的角度,決定顏色種類(如紅、綠、藍)。
  • 飽和度(Saturation, S)
    • 幾何位置:從圓柱中心到邊緣的徑向距離(0%–100%)。
    • 物理意義:顏色的鮮艷程度,中心為灰色,邊緣為純色。
  • 明度(Lightness, L)
    • 幾何位置:沿圓柱的垂直軸高度(0%–100%)。
    • 物理意義:顏色的明暗程度,底部為純黑,頂部為純白,中間為純色。

關鍵幾何特征

  • 灰度軸(中心軸)
    • 位置:圓柱的中心垂直線(S=0%)。
  • 顏色特性:
    • 所有點均為灰色,色相(H)無意義。
    • 明度(L)決定灰度深淺:
      • L=0% → 純黑
      • L=100% → 純白
      • L=50% → 中性灰
  • 中間平面(L=50%)
    • 位置:圓柱的中間水平截面(高度為 50%)。
    • 顏色特性:
      • 所有顏色處于最鮮艷狀態(飽和度 S=100%)。
      • 色相(H)在此平面上形成完整的 色相環(紅→黃→綠→青→藍→品紅→紅)。
  • 頂部與底部
    • 頂部(L=100%):
      • 所有顏色均為純白(無論色相和飽和度如何)。
    • 底部(L=0%):
      • 所有顏色均為純黑(無論色相和飽和度如何)。
        在這里插入圖片描述

(四)、什么是RGB

RGB(Red, Green, Blue)是一種基于光學的顏色表示方法,通過紅、綠、藍三原色的不同比例混合來定義顏色。它是數字設備(如顯示器、攝像頭)最基礎的顏色模型。

(五)、RGB中R、G、B分別代表什么

R:(Red,紅色)

  • 定義:紅色光的強度,是光的三原色之一。
  • 作用:紅色分量主導顏色中的紅色成分。
  • 示例:純紅色的 RGB 值為 (255, 0, 0)。

G(Green,綠色)

  • 定義:綠色光的強度,是光的三原色之一。
  • 作用:綠色分量主導顏色中的綠色成分。
  • 示例:純綠色的 RGB 值為 (0, 255, 0)。

B(Blue,藍色)

  • 定義:藍色光的強度,是光的三原色之一。
  • 作用:藍色分量主導顏色中的藍色成分。
  • 示例:純藍色的 RGB 值為 (0, 0, 255)。

(六)RGB的立方體模型

RGB 立方體模型是描述 RGB 顏色空間最直觀的幾何表示方式。它通過三維坐標系將紅(R)、綠(G)、藍(B)三個顏色分量的組合關系可視化,幫助理解顏色的混合規律和分布特性。

基本結構
RGB 立方體是一個三維直角坐標系:

  • 三個坐標軸:

    • R 軸(紅色):從左(0)到右(255 或 1.0)
    • G 軸(綠色):從前(0)到后(255 或 1.0)
    • B 軸(藍色):從下(0)到上(255 或 1.0)
  • 頂點:立方體的 8 個頂點對應極端顏色值,例如:

    • (0,0,0) → 純黑色
    • (255,255,255) → 純白色
    • (255,0,0) → 純紅色
    • (0,255,0) → 純綠色
    • (0,0,255) → 純藍色

關鍵幾何特征

  • 灰度對角線

    • 定義:從黑色 (0,0,0) 到白色 (255,255,255) 的對角線。
    • 顏色特性:線上所有點滿足 R=G=B,即 灰度色。
      • 例如:(128,128,128) → 中灰色。
  • 純色頂點

    • 6 個非黑白頂點:對應紅、綠、藍及其兩兩混合的純色:

      頂點坐標顏色名稱
      (255,0,0)純紅
      (0,255,0)純綠
      (0,0,255)純藍
      (255,255,0)黃(紅+綠)
      (255,0,255)品紅(紅+藍)
      (0,255,255)青(綠+藍)
  • 顏色平面

    • 單通道為 0 的平面:
      • R=0 平面 → 藍綠混合色(如青、藍、綠)。
      • G=0 平面 → 紅藍混合色(如品紅、紅、藍)。
      • B=0 平面 → 紅綠混合色(如黃、紅、綠)。
        在這里插入圖片描述
        歸一化如下圖
        歸一化

(七)、十六進制轉HSL

function hexToHsl(hex) {// 1. 去除#號并解析R,G,Blet r = parseInt(hex.slice(1, 3), 16) / 255;let g = parseInt(hex.slice(3, 5), 16) / 255;let b = parseInt(hex.slice(5, 7), 16) / 255;// 2. 計算最大值、最小值和色度(Chroma)let max = Math.max(r, g, b);let min = Math.min(r, g, b);let chroma = max - min;// 3. 計算明度(Lightness)let l = (max + min) / 2;// 4. 計算色相(Hue)和飽和度(Saturation)let h = 0, s = 0;if (chroma !== 0) {// 飽和度計算s = chroma / (1 - Math.abs(2 * l - 1));// 色相計算switch (max) {case r: h = ((g - b) / chroma) % 6; break;case g: h = (b - r) / chroma + 2; break;case b: h = (r - g) / chroma + 4; break;}h = h * 60;if (h < 0) h += 360; // 確保色相在0-360度之間}// 5. 返回HSL對象(色相四舍五入,飽和度和明度轉為百分比)return {h: Math.round(h),s: Math.round(s * 100),l: Math.round(l * 100)};
}

使用max - min計算色度的幾何意義

  let max = Math.max(r, g, b);let min = Math.min(r, g, b);let chroma = max - min;

色度表示顏色點 P(R,G,B) 到灰度軸的垂直距離,即顏色偏離灰色的程度。:

  • 當 C=0:顏色位于灰度軸上(完全無色彩)。
  • 當 C=1:顏色為純色(如純紅、純綠、純藍)。

總結:當某個分量(如R)遠大于其他分量時,max - min 的值越大,顏色越接近純色(如純紅)。

數學推導
顏色點到灰度軸的距離(三維空間中的垂直距離)為:
在這里插入圖片描述
而 C=max?min 是該距離的簡化近似,避免了復雜的平方根運算, 但是忽略了部分分量差異。會導致色度越大,顏色越偏離灰色。

根號3的來源,使用到了空間向量相關知識。公式如下
在這里插入圖片描述

使用(max - min)/2計算色度的幾何意義

 let l = (max + min) / 2;

明度表示顏色點在灰度軸上的投影位置。具體來說,顏色點 P(R,G,B)沿垂直于灰度軸的方向投影到灰度軸上,得到的投影點坐標為 (L,L,L)其中 L 是明度值。

  • 示例:
    • 純紅色 (1,0,0):
      L=(1+0)/2=0.5,投影點為 (0.5,0.5,0.5),即中等灰色。
    • 淺藍色 (0.2,0.8,0.8):
      L= (0.8+0.2)/2 =0.5,投影點仍為 (0.5,0.5,0.5)。

數學推導
在這里插入圖片描述
簡化公式為
在這里插入圖片描述
和色度一樣,使用(max+min)/2 計算明度只需比較和一次加法,適合實時計算(如早期圖形處理),同時還可以兼容HSL中飽和度的計算。

色度和明度對比

屬性幾何意義物理意義計算依賴
色度顏色到灰度軸的垂直距離顏色的純度(偏離灰色的程度)max 和 min 的差值
明度顏色在灰度軸上的投影位置顏色的整體亮度(等效灰色亮度)max 和 min 的平均值

使用chroma / (1 - Math.abs(2 * l - 1))計算飽和度的幾何意義

 s = chroma / (1 - Math.abs(2 * l - 1));

在這里插入圖片描述
這相當于:

  • 在RGB立方體中,從當前顏色點向灰度軸作垂線
  • 計算該點到灰度軸的距離(實際色度)
  • 計算該明度平面上可能的最大色度
  • 求兩者的比值

可視化理解:

  • 想象RGB立方體:
    • 在L=0.5的中間平面,最大色度大(分母大),容易得到高飽和度
    • 在L接近0或1的平面,最大色度小(分母小),飽和度被壓縮
  • 這種設計確保了:
    • 純色總是在L=0.5時S=100%
    • 接近黑白時飽和度自動降低

計算色相的幾何意義

 switch (max) {case r: h = ((g - b) / chroma) % 6; break;case g: h = (b - r) / chroma + 2; break;case b: h = (r - g) / chroma + 4; break;}

為什么計算色相時需要分三段進行判斷?

色相表示顏色在色輪上的位置(0°~360°),不同主色對應不同區間:

  • 紅色(R):0°(或360°)
  • 綠色(G):120°
  • 藍色(B):240°

色相的計算需要根據最大值通道確定基礎角度,再通過其他通道的相對差異調整偏移量。

當最大值是R時

case r: h = ((g - b) / chroma) % 6; break; // 這里 % 6 是為了防止差值出超過0-6之間的數值。如果差值超過0-6的范圍那么%6可以回到范圍
  • 基礎角度:0°(紅色)
  • 偏移方向:
    • 若G > B → 向黃色(60°方向)偏移。
    • 若B > G → 向品紅色(300°方向)偏移。
  • 計算公式:
    • 在這里插入圖片描述
    • 幾何意義:計算G和B的相對比例,歸一化到[-1,1],再映射到0-6的臨時值。

當最大值是G時

case g: h = (b - r) / chroma + 2; break;
  • 基礎角度:120°(綠色)
  • 偏移方向:
    • 若B > R → 向青色(180°方向)偏移。
    • 若R > B → 向黃色(60°方向)偏移。
  • 計算公式:
    • 在這里插入圖片描述
    • 幾何意義:+2 將結果偏移到綠色區域(120°)。

當最大值是B時

  • 基礎角度:240°(藍色)
  • 偏移方向:
    • 若R > G → 向品紅色(300°方向)偏移。
    • 若G > R → 向青色(180°方向)偏移。
  • 計算公式:
    • 在這里插入圖片描述
    • 幾何意義:+4 將結果偏移到藍色區域(240°)

為什么計算色相時當最大值為r時公式里面是g-b為不是b-g?

色輪以 逆時針方向 定義顏色過渡:
紅色(0°) → 黃色(60°) → 綠色(120°) → 青色(180°) → 藍色(240°) → 品紅(300°) → 紅色(360°)。
當 R為最大值 時:
若 G > B,顏色偏向 黃色(60°方向),此時 (G - B) 為正,色相應 增加。
若 B > G,顏色偏向 品紅色(300°方向),此時 (G - B) 為負,色相應 減少。
使用 (G - B) 而非 (B - G) 能直接反映這一方向性。(同樣道理適用于最大值為g或b)

四、HSL轉十六進制

function hslToHex(h, s, l) {// 規范化輸入值h = h % 360;s = Math.max(0, Math.min(100, s)) / 100;l = Math.max(0, Math.min(100, l)) / 100;// 處理灰度色if (s === 0) {const gray = Math.round(l * 255);return `#${gray.toString(16).padStart(2, '0').repeat(3)}`;}// 計算色度、中間值和明度偏移const c = (1 - Math.abs(2 * l - 1)) * s;const x = c * (1 - Math.abs((h / 60) % 2 - 1));const m = l - c / 2;// 根據色相確定RGB初始值let r, g, b;if (h >= 0 && h < 60) {[r, g, b] = [c, x, 0];} else if (h < 120) {[r, g, b] = [x, c, 0];} else if (h < 180) {[r, g, b] = [0, c, x];} else if (h < 240) {[r, g, b] = [0, x, c];} else if (h < 300) {[r, g, b] = [x, 0, c];} else {[r, g, b] = [c, 0, x];}// 轉換為十六進制const toHex = (value) => {const hex = Math.round((value + m) * 255).toString(16);return hex.padStart(2, '0');};return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

獲取色度

const c = (1 - Math.abs(2 * l - 1)) * s;

是上面十六進制轉為HSL中飽和度s=chroma / (1 - Math.abs(2 * l - 1)); 再乘以(1 - Math.abs(2 * l - 1))得到色度

計算中間顏色分量的值

const x = c * (1 - Math.abs((h / 60) % 2 - 1));

分步理解公式

  • 色相分段:h / 60
    • 將色相 H 按每 60° 分段,對應色輪上的 6 個主色區間(紅、黃、綠、青、藍、品紅)。
  • 模2操作:(h / 60) % 2
    • 將分段后的色相值映射到 0~2 的范圍內,用于在每段內生成對稱的插值系數。
  • 歸一化到 -1~1:(h / 60) % 2 - 1
    • 通過減去 1,將范圍調整為 -1~1,便于后續的絕對值處理。
  • 生成插值系數:1 - Math.abs(…)
    • 取絕對值后,值域為 0~1,再用 1 減去它,得到 0→1→0 的三角形波形,用于顏色分量的平滑過渡。
  • 乘以色度 C:c * …
    • 最終結果表示中間顏色分量的強度,范圍在 0~C 之間。

為什么乘以色度?

  • 色度 C 表示顏色的純度,插值系數與 C 相乘,確保顏色強度與飽和度一致。
    • 高飽和度( 最大,顏色鮮艷)。
    • 低飽和度(顏色為灰色)。

中間顏色分量的幾何意義:

色相分段與顏色過渡

  • 每 60° 對應一個顏色區間:
    • 0°~60°:紅色 → 黃色
    • 60°~120°:黃色 → 綠色
    • 120°~180°:綠色 → 青色
    • 180°~240°:青色 → 藍色
    • 240°~300°:藍色 → 品紅
    • 300°~360°:品紅 → 紅色
  • 中間分量的作用:
    在每個區間內,一個顏色分量保持最大值(由主色決定),另一個分量從 0 增長到最大值(或從最大值減少到 0),第三個分量保持為 0。
    • 例如:在 0°~60°(紅→黃)區間:
      • 紅色分量 R=C(最大)
      • 綠色分量 G=C×插值系數(從 0 到 C)
      • 藍色分量 B=0。

插值系數的波形

  • 波形形狀:
    插值系數通過 1 - Math.abs((h / 60) % 2 - 1) 生成 三角形波形,在每 60° 區間內從 0 線性增長到 1,再線性減少到 0。
    • 示例:當 H=30°(0°~60°區間):
      插值系數=1?∣(30/60)%2?1∣=1?∣0.5?1∣=0.5
      此時綠色分量 G=C×0.5,顏色為橙色。

計算明度偏移量

const m = l - c / 2;

計算明度偏移量的幾何意義

平移中間分量:將中間分量(如 r′,g′,b ′)從相對范圍 0~C 平移到實際范圍 L? C/2~L+ C/2,保顏色在灰度軸上的投影亮度為 L。

計算明度偏移量的數據推導

HSL明度的定義:

  • 在HSL模型中,明度 L 是RGB分量的最大值(max)和最小值(min)的算術平均值
    • 在這里插入圖片描述

色度 C 的定義:

  • 色度(Chroma) 表示顏色的純度,即RGB分量的最大值與最小值之差:
    • 在這里插入圖片描述

聯立方程求解

  • 通過聯立上述兩個方程,可以推導出 min 和 max:
    • 在這里插入圖片描述
    • max:顏色分量的最大值(例如純紅色時 R=1)
    • min:顏色分量的最小值(例如純紅色時 G=B=0)

明度偏移量 m 的引入
在HSL轉RGB時,中間分量(如 r ′,g ′,b ′)是基于色相和飽和度計算出的相對值(范圍0~C)。為了將這些中間分量映射到實際RGB值(范圍0~1),需要加上一個偏移量 m,使得:
在這里插入圖片描述
將 m=L? C/2代入,可保證:
在這里插入圖片描述
從而滿足HSL明度的定義。

根據色相區間確定 RGB 初始值

  let r, g, b;if (h >= 0 && h < 60) {[r, g, b] = [c, x, 0];} else if (h < 120) {[r, g, b] = [x, c, 0];} else if (h < 180) {[r, g, b] = [0, c, x];} else if (h < 240) {[r, g, b] = [0, x, c];} else if (h < 300) {[r, g, b] = [x, 0, c];} else {[r, g, b] = [c, 0, x];}
色相區間臨時 RGB 值
0°-60°(C, X, 0)
60°-120°(X, C, 0)
120°-180°(0, C, X)
180°-240°(0, X, C)
240°-300°(X, 0, C)
300°-360°(C, 0, X)

調整 RGB 值并轉換為十六進制

 const toHex = (value) => {const hex = Math.round((value + m) * 255).toString(16);return hex.padStart(2, '0');};
  • 將 RGB 值加上明度偏移量 m,并限制在 0-1 范圍內。
  • 轉換為 0-255 的整數,再轉為兩位十六進制。

五、十六進制轉HSV

雖然HSV和HSL看著名字相似,但它們的定義和計算邏輯有本質區別。盡管在十六進制→HSL 和 十六進制→HSV(HSV → 十六進制 和 HSL → 十六進制) 的轉換過程中,計算中間值(如色度 c 和輔助變量 x)或者色度等公式看起來相似,但它們的物理含義不同,最終轉換結果也不同

(一)、什么是HSV

HSV(Hue, Saturation, Value)是一種基于人類顏色感知的模型,用于直觀描述顏色的 色調、鮮艷度 和 亮度。它在圖像處理、設計工具和數據可視化中廣泛應用。

(二)、HSV中H、S、V分別代表什么

H:色相(Hue, H)

  • 定義:顏色的基本類型(如紅、綠、藍)。
  • 范圍:0°–360°(環形色輪)。
    0° = 紅色
    120° = 綠色
    240° = 藍色
    360° = 回到紅色

S:飽和度(Saturation, S)

  • 定義:顏色的鮮艷程度(從灰度到純色)。
  • 范圍:0%–100%
    0% = 灰色(完全去色)
    100% = 最鮮艷的顏色

V:明度(Value,V)

  • 定義:顏色的亮度。明度越高,顏色越亮;越低則越暗。
  • 范圍:0%(純黑)–100%(最亮,顏色保持純色)。
    V=100%:亮紅色(RGB的紅色通道全開)。
    V=50%:暗紅色(亮度減半)。
    V=0%:純黑色(所有顏色通道關閉)。

(三)、HSV和HSL的區別

模型定義公式幾何意義示例(純紅色)適用場景核心優勢
HSVV=max(R,G,B)顏色的最大亮度(最亮時顏色保持純色)V=100% → 純紅(RGB: 255,0,0)圖像處理、快速調色直觀調整顏色亮度
HSLL= (max+min)/2顏色的平均亮度(中等亮度時顏色最純)L=50% → 純紅(RGB: 255,0,0)設計、數據可視化自然保持顏色鮮艷度

(四)、HSV的圓柱模型

HSV還有單六棱錐模型,這里主要說圓柱模型

基本結構

HSV 圓柱模型由三個正交維度構成,分別對應色相(H)、飽和度(S)、明度(V):

  • 色相(Hue)

    • 幾何方向:沿圓柱的 圓周分布,角度范圍為 0°–360°。
    • 物理意義:決定顏色的基本類型(如紅、綠、藍等)。
  • 飽和度(Saturation)

    • 幾何方向:沿圓柱的 徑向分布,范圍 0%(中心)–100%(邊緣)。
    • 物理意義:表示顏色純度(鮮艷程度)。
  • 明度(Value)

    • 幾何方向:沿圓柱的 垂直軸分布,范圍 0%(底部)–100%(頂部)。
    • 物理意義:控制顏色亮度(明暗程度)。

關鍵幾何特征

  • 色相環的連續性
    • 圓周閉合性:色相角度 0° 與 360° 重合,顏色從紅→黃→綠→青→藍→品紅→紅無縫過渡。
    • 幾何意義:圓柱的圓周方向形成閉環,確保顏色過渡無間斷。
  • 飽和度與徑向距離
    • 中心軸為灰度軸:當 S=0% 時,無論 H 和 V 如何,顏色均為不同明度的灰色(如深灰、淺灰)。
    • 邊緣為純色:當 S=100% 時,顏色達到最大純度,對應 RGB 的純色(如紅、綠、藍)。
  • 底部為純黑(V=0%):所有顏色在 V=0% 時均變為黑色,與 H 和 S 無關。
    • 頂部為最亮純色(V=100%):顏色保持最大亮度,但可能因 S 不同呈現不同鮮艷度。
      • 示例:
        • V=100%、S=100% → 純紅色(RGB: 255,0,0)。
        • V=100%、S=50% → 淺紅色(RGB: 255,128,128)。
  • 顏色過渡規律
    • 垂直方向(調整 V):
      • 顏色亮度線性變化,但飽和度不變。
      • 示例:V 從 50%→100%,顏色從暗紅→亮紅,但始終為紅色(H 固定)。
    • 徑向方向(調整 S):
      • 顏色從中心灰色逐漸變為邊緣純色。
      • 示例:S 從 0%→100%,顏色從灰→淺紅→純紅。
    • 圓周方向(調整 H):
      • 顏色種類周期性變化,色輪角度對應不同顏色類型。
      • 示例:H 從 0°→60°,顏色從紅→橙→黃。

在這里插入圖片描述

(五)、十六進制轉HSV

function hexToHsv(hex) {// 1. 移除#號并解析R, G, B分量(0~255)hex = hex.replace(/^#/, '');let r, g, b;if (hex.length === 3) {// 處理簡寫格式(如 #RGB → #RRGGBB)r = parseInt(hex[0] + hex[0], 16);g = parseInt(hex[1] + hex[1], 16);b = parseInt(hex[2] + hex[2], 16);} else {r = parseInt(hex.substring(0, 2), 16);g = parseInt(hex.substring(2, 4), 16);b = parseInt(hex.substring(4, 6), 16);}// 2. 歸一化到0~1范圍r /= 255, g /= 255, b /= 255;// 3. 計算最大值、最小值和色度(Chroma)const max = Math.max(r, g, b);const min = Math.min(r, g, b);const chroma = max - min;// 4. 計算明度(Value)const v = max;// 5. 計算飽和度(Saturation)let s = max === 0 ? 0 : chroma / max;// 6. 計算色相(Hue)let h = 0;if (chroma !== 0) {switch (max) {case r:h = ((g - b) / chroma) % 6;break;case g:h = (b - r) / chroma + 2;break;case b:h = (r - g) / chroma + 4;break;}h = (h * 60 + 360) % 360; // 確保角度在0~360之間}// 7. 轉換為百分比并四舍五入return {h: Math.round(h),s: Math.round(s * 100),v: Math.round(v * 100)};
}

計算色度

  const chroma = max - min;

原理和HSL一樣,不再贅訴

計算明度

   const v = max;

根據HSL模型定義,明度直接取最大值

計算飽和度

  let s = max === 0 ? 0 : chroma / max;

為什么在計算飽和度時HSV和HSL兩個模型公式不一樣?

這源于兩者對顏色亮度的定義差異以及幾何模型的根本區別

HSV/HSL中對S公式理解

  • HSV 的飽和度公式
    • 在這里插入圖片描述
    • 物理意義:
      • 飽和度是 色度(Chroma)占當前明度(V)的比例。
      • 明度 V 是 RGB 的最大值,因此飽和度表示顏色純度相對于最大亮度的占比。
        • 純紅色(RGB(255,0,0)):V=1,Chroma=1→S=100%。
        • 淺紅色(RGB(255,128,128)):V=1,Chroma=0.5→S=50%。
  • HSL 的飽和度公式
    • 在這里插入圖片描述
    • 物理意義:
      • 飽和度是 色度占當前亮度下可能的最大色度的比例。
      • 分母 1?∣2L?1∣ 表示當前亮度 L 下允許的最大色度。
        • 當 L=0.5(中等亮度)時,分母為 1,飽和度 S=Chroma
        • 當 L→0 或 L→1(接近黑/白)時,分母趨近 0,飽和度被壓縮。

計算色相

 if (chroma !== 0) {switch (max) {case r:h = ((g - b) / chroma) % 6;break;case g:h = (b - r) / chroma + 2;break;case b:h = (r - g) / chroma + 4;break;}h = (h * 60 + 360) % 360; // 確保角度在0~360之間}

原理和HSL一樣,不再贅訴

六、HSV轉十六進制

function hsvToHex(h, s, v) {// 1. 規范化輸入值h = ((h % 360) + 360) % 360; // 確保色相在0~360之間s = Math.max(0, Math.min(100, s)) / 100; // 飽和度轉為0~1v = Math.max(0, Math.min(100, v)) / 100; // 明度轉為0~1// 2. 處理飽和度為0的情況(灰度色)if (s === 0) {const gray = Math.round(v * 255);return `#${gray.toString(16).padStart(2, '0').repeat(3)}`;}// 3. 計算色度、中間值和明度偏移const c = v * s;const x = c * (1 - Math.abs(((h / 60) % 2) - 1));const m = v - c;// 4. 根據色相區間確定RGB初始值let r, g, b;if (h < 60) {[r, g, b] = [c, x, 0];} else if (h < 120) {[r, g, b] = [x, c, 0];} else if (h < 180) {[r, g, b] = [0, c, x];} else if (h < 240) {[r, g, b] = [0, x, c];} else if (h < 300) {[r, g, b] = [x, 0, c];} else {[r, g, b] = [c, 0, x];}// 5. 調整RGB值并轉換為十六進制const toHex = (value) => {const hex = Math.round((value + m) * 255).toString(16);return hex.padStart(2, '0');};return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

計算色度

  const c = v * s;

在HSV中為什么計算色度公式是v * s?

色度 c 是顏色在 RGB 空間中的最大分量與最小分量的差值,表示顏色的“純度”或“鮮艷程度”。在 HSV 模型中:

  • 當 S = 1 時,顏色為純色,色度 c 達到最大值(c = V)。
  • 當 S = 0 時,顏色為灰色,色度 c = 0。
  • 因此,色度 c 是飽和度和明度的乘積:
    c = V * S

計算中間值

const x = c * (1 - Math.abs(((h / 60) % 2) - 1));

這里和上面HSL轉十六進制時求x理解一致(這是因為在十六進制轉為HSL和十六進制轉為HSV轉換中對色相的處理方式完全相同)

明度偏移

const m = v - c;

為什么HSL或HSV轉為十六進制 m 的計算方式不同?

  • HSV

    • 在 RGB 中,max(R, G, B) = v(由 v 決定)
    • min(R, G, B) = v - c(因為 c = max - min)。
    • 所以 m 的作用是 確保 min(R, G, B) 正確,使得:
      • 當 s = 1 時,c = v,m = 0(純色,最小值是 0)。
      • 當 s = 0 時,c = 0,m = v(灰度,所有分量等于 v)。
  • HSL

    • 在 RGB 中,(max + min) / 2 = l(由 l 決定)。
    • c = max - min(色度)。
    • 所以 min = l - c / 2(因為 max = min + c,代入 (max + min)/2 = l 可得)。
    • m 的作用是 確保 min(R, G, B) 正確,使得:
      • 當 s = 1 且 l = 0.5 時,c = 1,m = 0.5 - 0.5 = 0(純色)。
      • 當 s = 0 時,c = 0,m = l(灰度,所有分量等于 l)。

參考文章

  1. 由RGB到HSV的轉換詳解
  2. 13 個 顏色轉換 的高級方法🌈
  3. 3D空間點到直線的距離
  4. 漫步色彩空間:解鎖HSV(HSB)的奧秘

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/78747.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/78747.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/78747.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

智能資源管理機制-重傳機制

一、發送端資源管理的核心機制 1. 滑動窗口&#xff08;Sliding Window&#xff09; 這是TCP協議的核心優化設計&#xff1a; 窗口動態滑動&#xff1a;發送端不需要保留所有已發送的分組&#xff0c;只需維護一個"發送窗口"窗口大小&#xff1a;由接收方通告的接…

基于SSM+Layui畢業設計選題系統源碼

項目介紹 基于SSM+Layui畢業設計選題系統源碼,可以作為課程設計項目參考,該系統分為三個角色: 管理員:用戶管理(對學生和老師的信息進行維護),統計分析(對老師課題情況以及學生選題情況信息進行維護),修改密碼 老師:個人信息維護,畢業設計題目管理,報名學生管理…

通過uri獲取文件路徑手機適配

青銅版本 return contentResolver.query(this, arrayOf(MediaStore.MediaColumns.DATA), null, null).let {if (it?.moveToFirst() true) {val columnIndex it.getColumnIndex(MediaStore.MediaColumns.DATA)val path it.getString(columnIndex)it.close()return path}&quo…

vue模擬撲克效果

vue模擬撲克效果 效果圖&#xff1a; step1:C:\Users\wangrusheng\PycharmProjects\untitled18\src\views\Home.vue <template><div class"poker-container"><!-- 使用復合數據對象實現雙行顯示 --><divv-for"(card, index) in POKER_…

基礎數學:圖論與信息論

微積分與概率論由此進&#xff1a;基礎數學&#xff1a;微積分和概率與統計-CSDN博客 線代與優化理論由此進&#xff1a;基礎數學&#xff1a;線性代數與優化理論-CSDN博客 數值分析與離散數學由此進&#xff1a;基礎數學&#xff1a;數值分析與離散數學-CSDN博客 四、圖論與…

構建智能期貨交易策略分析應用:MCP與AI的無縫集成

引言 隨著金融科技的快速發展&#xff0c;數據驅動的交易決策已成為期貨交易領域的重要趨勢。本文將深入探討一個結合了Model Content Protocol (MCP)和AI技術的期貨交易策略分析應用——Futures MCP。該應用不僅提供了豐富的技術分析工具&#xff0c;還通過MCP協議與大型語言…

0x02.Redis 集群的實現原理是什么?

回答重點 Redis 集群&#xff08;Redis cluster&#xff09;是通過多個 Redis 實例組成的&#xff0c;每個主節點實例負責存儲部分的數據&#xff0c;并且可以有一個或多個從節點作為備份。 具體是采用哈希槽&#xff08;Hash Slot&#xff09;機制來分配數據&#xff0c;將整…

基本的DOS命令

一.打開CMD方式&#xff1a; winR 輸入cmd 開始系統命令提示符 在任意文件夾下&#xff0c;shift&#xff0b;鼠標右擊&#xff0c;在此處打開命令 資源管理器的地址欄前面輸入cmd 以管理員身份打開cmd&#xff1a;選擇以管理員方式運行 二.常用的Dos命令 #盤符切換 盤符…

深度剖析:架構評估的常用方法與應用

架構評估是確保系統架構滿足需求、性能和質量等方面要求的重要環節&#xff0c;以下是一些常見的架構評估方法的詳細介紹&#xff1a; 一、基于調查問卷或檢查表的評估方法 1.方法概述&#xff1a;該方法通過設計一系列針對性的問題或檢查項&#xff0c;形成問卷或檢查表&…

代碼隨想錄算法訓練營第十六天

LeetCode題目: 530. 二叉搜索樹的最小絕對差501. 二叉搜索樹中的眾數236. 二叉樹的最近公共祖先3272. 統計好整數的數目(每日一題) 其他: 今日總結 往期打卡 530. 二叉搜索樹的最小絕對差 跳轉: 530. 二叉搜索樹的最小絕對差 學習: 代碼隨想錄公開講解 問題: 給你一個二叉搜…

基于雙閉環PID控制器的永磁同步電機控制系統匝間故障Simulink仿真

歡迎微?關注“電擊小子程高興的MATLAB小屋”獲取巨額優惠 1.模型簡介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2013Rb&#xff09;軟件。建議采用matlab2013 Rb及以上版本打開。&#xff08;若需要其他版本可聯系代為轉換&#xff0c;高于該版本的matlab均可正…

02-libVLC的視頻播放器:播放音視頻文件以及網絡流

libvlc_new(0, nullptr)功能:創建并初始化libVLC的核心實例,是使用所有libVLC功能的前提。 參數:第一個參數:參數數量(通常設為0)第二個參數:參數列表(通常為nullptr,表示使用默認配置)返回值:成功返回libvlc_instance_t*指針,失敗返回nullptr。注意事項:可通過參…

2025藍橋杯省賽C++B組解題思路

由于題面還沒出來&#xff0c;現在先口胡一下思路 填空題直接打表找規律或者亂搞一下就能出&#xff0c;從大題開始說。 1&#xff0c;題意&#xff1a; 給你一個數組&#xff0c;這個數組里有幾個數可以被一個連續遞增的數字區間求和得出 思路&#xff1a;詐騙題&#xff0c;顯…

防止郵件偽造的策略 SPF 介紹

SPF是Sender Policy Framework的縮寫&#xff0c;即發件人策略框架&#xff0c;是一種用于防止電子郵件偽造的技術&#xff0c;用來驗證發件人郵箱域名的真實性。以下是關于它的詳細說明&#xff1a; 1. 定義與作用 SPF是一種電子郵件驗證系統&#xff0c;它通過在域名的DNS記…

JavaScript Symbol與BigInt

目錄 Symbol類型 一、Symbol 的核心特性 1. 唯一性 2. 不可變性 3. 不可枚舉性 二、創建 Symbol 1. 基礎創建 2. 全局 Symbol 注冊表 三、Symbol 作為對象屬性 1. 定義 Symbol 屬性 2. 遍歷 Symbol 屬性 四、內置 Symbol 值 五、實際應用場景 1. 避免屬性名沖突 …

AI Agent工程師認證-學習筆記(3)——【多Agent】MetaGPT

學習鏈接:【多Agent】MetaGPT學習教程 源代碼鏈接(覺得很好,star一下):GitHub - 基于MetaGPT的多智能體入門與開發教程 MetaGPT鏈接:GitHub - MetaGPT 前期準備 1、獲取MetaGPT (1)使用pip獲取MetaGPT pip install metagpt==0.6.6#或者在國內加速安裝鏡像 #pip in…

【leetcode hot 100 416】分割等和子集

解法一&#xff1a;&#xff08;動態規劃&#xff09;①定義&#xff1a;dp[i]表示是否可以在nums找到元素之和為i&#xff0c;dp[sum/21] ②初始狀態&#xff1a;dp[0]true;dp[i]false ③狀態轉移方程&#xff1a;dp[i] dp[i] || dp[i - num]; class Solution {public boole…

高中數學聯賽模擬試題精選第2套幾何題(改編)

在 △ A B C \triangle ABC △ABC 中, 點 M M M 是邊 A C AC AC 的中點. 在線段 A M AM AM, C M CM CM 上分別取點 P P P, Q Q Q, 使得 P Q A C / 2 PQAC/2 PQAC/2. 設 △ A B Q \triangle ABQ △ABQ 的外接圓與邊 B C BC BC 相交于點 X X X, △ B C P \triangle …

UWB雙通道隧道人員定位方案

技術基礎&#xff1a;UWB&#xff08;超寬帶技術&#xff09; 定義&#xff1a;UWB&#xff08;Ultra-Wideband&#xff09;是一種通過納秒級窄脈沖傳輸數據的無線通信技術&#xff0c;占用500MHz以上的超寬頻段。 核心優勢&#xff1a; 高精度定位&#xff1a;時間分辨率極高&…

Linux 入門八:Linux 多進程

一、概述 1.1 什么是進程&#xff1f; 在 Linux 系統中&#xff0c;進程是程序的一次動態執行過程。程序是靜態的可執行文件&#xff0c;而進程是程序運行時的實例&#xff0c;系統會為其分配內存、CPU 時間片等資源。例如&#xff0c;輸入 ls 命令時&#xff0c;系統創建進程…