分享乙個演算法,計算能在任何背景色上清晰顯示的前景色

2022-01-15 14:47:46 字數 1846 閱讀 6127

背景色千差萬別,如果希望在這樣複雜的背景色下顯示清晰可辨的前景色(例如顯示文字),那如何選擇這樣的前景色才能確保適用於所有的背景呢?

紅綠藍三色是非常不直觀的顏色表示的方法,如果不經過訓練,人類幾乎沒有辦法直接通過 rgb 的值來猜出大概的顏色來。而 hsb 是用來解決人眼感知問題的,它將顏色用色相、飽和度、明度來表示。

可是,即便是 hsb 也不能完美解決人眼的感知問題。看下圖,黃色和藍色的飽和度和明度一樣,只是色相不同,你覺得哪乙個顏色更亮,哪乙個更暗?

相信大家都會覺得黃色更亮,藍色總給人一種陰暗的感覺。

所以,在飽和度和明度之外,一定還有一種人眼對亮度的感覺是與色相相關的。

我們將不同色相的顏色排成一圈,觀察下哪些顏色更亮,哪些更暗:

我們將上面的不同顏色直接轉成灰度影象,這是最能反映人眼感知的灰度影象,它將是這樣的:

也就是說,不同的顏色值總能找到乙個人眼感知的灰度值,這是著名的心理學公式:

灰度 = 紅×0.299 + 綠×0.587 + 藍×0.114

乙個影象的每乙個畫素經過上面的公式計算得到的新的影象,即是人眼感知亮度的灰度圖。

於是,當我們期望計算乙個能在背景色上清晰顯示的前景色時,我們可將背景顏色轉換為灰度顏色,然後根據灰度程度,選取黑色或白色作為前景色。

為了實現這個效果,我們先寫乙個灰度/亮度的計算函式:

///

/// 獲取乙個顏色的人眼感知亮度,並以 0~1 之間的小數表示。

///private

static

double

getgraylevel(color color)

然後寫乙個根據感知亮度計算反色的方法:

private

static color getreverseforegroundcolor(double graylevel) => graylevel > 0.5 ? colors.black : colors.white;

於是,當我們希望計算某個背景色上一定能清晰顯示的前景色時,只需要呼叫getreverseforegroundcolor即可。

不過,總是寫後台**來計算,對於 xaml 類的程式來說還是麻煩了些,於是我寫了一些用於 xaml 的標記擴充套件,方便讓一些文字自動根據背景色改變顏色。

這是期望的最簡用法:

foreground=""

text="我是前景 by walterlv"/>

因為內部已經使用繫結來實現動態變化,所以,無需在顏色更改時再次更新:

參考資料

兩個文字框異動任何乙個能即時更新計算結果

在gridview控制項中,有兩個文字框,使用者更改某乙個文字框的值,能即時計算結果。insus.net列舉乙個小例子,來演示些功能。先建立乙個物件 類 在網頁中,建立乙個集合,假設說,一張採購單有多個物品元件,這樣說,採購單就是乙個集合,不過些例,只是採購乙個物品。把上面的集合,繫結給gridvi...

又乙個PHP實現的氣泡排序演算法分享

經典的氣泡排序法一直是許多程式沿用的其中一種排序法,話說氣泡排序法在效率上比php系統函式sort更高效。本章不討論效能,所以就不拿它來跟系統效能做對比了。氣泡排序大概的意思是依次比較相鄰的兩個數,然後根據大小做出排序,直至最後兩位數。由於在排序過程中總是小數往前放,大數往後放,相當於氣泡往上公升,...

分享乙個即插即用的私藏緩動動畫JS小演算法

原理如下 假設要從數值a變化到數值b,如果是線性運動,則每次移動距離是一樣 如果是緩動,每次移動距離不一樣。那如何才能不一樣呢?很簡單,按比例移動就可以。例如 每次移動剩餘距離的一半。對吧,超容易理解的。比方說 你和初戀之間距離是64,每秒移動一半,則,你們之間的距離下一秒就是32,再下一秒就是16...