国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
計劃
步驟1:從畫布讀取圖像顏色
步驟2:找到對比度最小的像素
步驟4:找到達(dá)到對比度目標(biāo)的疊加不透明度
改進(jìn)和局限性
我在此過程中學(xué)習(xí)到了一些東西
首頁 web前端 css教程 釘在光文和背景圖像之間的完美對比度

釘在光文和背景圖像之間的完美對比度

Apr 03, 2025 am 09:44 AM

Nailing the Perfect Contrast Between Light Text and a Background Image

您是否遇到過網(wǎng)站上淺色文本疊加在淺色背景圖片上的情況?如果遇到過,您就會知道這有多難閱讀。避免這種情況的一種常用方法是使用透明疊加層。但這引出一個重要問題:疊加層的透明度究竟應(yīng)該有多高?我們并非總是處理相同的字體大小、粗細(xì)和顏色,當(dāng)然,不同的圖片也會產(chǎn)生不同的對比度。

嘗試消除背景圖片上文本對比度差的問題,就像玩打地鼠游戲一樣。與其猜測,不如使用HTML <canvas></canvas>和一些數(shù)學(xué)方法來解決這個問題。

就像這樣:

我們可以說“問題解決了!”,然后就此結(jié)束這篇文章。但這有什么樂趣呢?我想向您展示的是這個工具的工作原理,以便您掌握一種處理這種常見問題的新方法。

計劃

首先,讓我們明確我們的目標(biāo)。我們說過,我們想要在背景圖片上顯示可讀的文本,但“可讀”究竟意味著什么?就我們的目的而言,我們將使用WCAG對AA級可讀性的定義,該定義指出文本和背景顏色之間需要足夠的對比度,以便一種顏色比另一種顏色亮4.5倍。

讓我們選擇一種文本顏色、一張背景圖片和一種疊加顏色作為起點。給定這些輸入,我們想要找到使文本可讀的疊加不透明度級別,而不會使圖片隱藏太多,以至于圖片也難以看到。為了使事情復(fù)雜化一點,我們將使用一張既有深色空間又有淺色空間的圖片,并確保疊加層考慮到了這一點。

我們的最終結(jié)果將是一個值,我們可以將其應(yīng)用于疊加層的CSS不透明度屬性,該屬性使文本比背景亮4.5倍。

為了找到最佳疊加不透明度,我們將執(zhí)行四個步驟:

  1. 我們將圖片放入HTML <canvas></canvas>中,這將使我們能夠讀取圖片中每個像素的顏色。
  2. 我們將找到圖片中與文本對比度最小的像素。
  3. 接下來,我們將準(zhǔn)備一個顏色混合公式,我們可以使用它來測試不同不透明度級別對該像素顏色的影響。
  4. 最后,我們將調(diào)整疊加層的不透明度,直到文本對比度達(dá)到可讀性目標(biāo)。這不會是隨機猜測——我們將使用二分查找技術(shù)來加快此過程。

讓我們開始吧!

步驟1:從畫布讀取圖像顏色

Canvas允許我們“讀取”圖像中包含的顏色。為此,我們需要將圖像“繪制”到<canvas></canvas>元素上,然后使用canvas上下文(ctx)的getImageData()方法生成圖像顏色的列表。

function getImagePixelColorsUsingCanvas(image, canvas) {
  // canvas的上下文(通??s寫為ctx)是一個包含許多函數(shù)的對象,用于控制你的canvas
  const ctx = canvas.getContext('2d');

  // 寬度可以是任何值,所以我選擇500,因為它足夠大,可以捕捉細(xì)節(jié),但又足夠小,可以使計算速度加快。
  canvas.width = 500;

  // 確保canvas與我們圖像的比例匹配
  canvas.height = (image.height / image.width) * canvas.width;

  // 獲取圖像和canvas的測量值,以便我們可以在下一步中使用它們
  const sourceImageCoordinates = [0, 0, image.width, image.height];
  const destinationCanvasCoordinates = [0, 0, canvas.width, canvas.height];

  // Canvas的drawImage()的工作原理是將我們圖像的測量值映射到我們想要繪制它的canvas上
  ctx.drawImage(
    image,
    ...sourceImageCoordinates,
    ...destinationCanvasCoordinates
  );

  // 請記住,getImageData僅適用于相同來源或啟用跨源的圖像。
  // https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
  const imagePixelColors = ctx.getImageData(...destinationCanvasCoordinates);
  return imagePixelColors;
}

getImageData()方法為我們提供了一個表示每個像素顏色的數(shù)字列表。每個像素由四個數(shù)字表示:紅色、綠色、藍(lán)色和不透明度(也稱為“alpha”)。了解這一點,我們可以遍歷像素列表并找到我們需要的任何信息。這在下一步中將非常有用。

步驟2:找到對比度最小的像素

在此之前,我們需要知道如何計算對比度。我們將編寫一個名為getContrast()的函數(shù),該函數(shù)接收兩種顏色并輸出一個數(shù)字,表示這兩種顏色之間的對比度級別。數(shù)字越高,對比度越好,可讀性也越好。

當(dāng)我開始研究這個項目的顏色時,我期望找到一個簡單的公式。結(jié)果發(fā)現(xiàn)有多個步驟。

要計算兩種顏色之間的對比度,我們需要知道它們的亮度級別,這本質(zhì)上就是亮度(Stacie Arellano對亮度進(jìn)行了深入探討,值得一看)。

感謝W3C,我們知道使用亮度計算對比度的公式:

const contrast = (lighterColorLuminance   0.05) / (darkerColorLuminance   0.05);

獲取顏色的亮度意味著我們必須將顏色從網(wǎng)絡(luò)上使用的常規(guī)8位RGB值(其中每種顏色為0-255)轉(zhuǎn)換為所謂的線性RGB。我們需要這樣做是因為亮度不會隨著顏色的變化而均勻增加。我們需要將顏色轉(zhuǎn)換為亮度隨顏色變化均勻變化的格式。這使我們能夠正確計算亮度。同樣,W3C在這里也提供了幫助:

const luminance = (0.2126 * getLinearRGB(r)   0.7152 * getLinearRGB(g)   0.0722 * getLinearRGB(b));

但是,等等,還有更多!為了將8位RGB(0到255)轉(zhuǎn)換為線性RGB,我們需要經(jīng)歷所謂的標(biāo)準(zhǔn)RGB(也稱為sRGB),其比例為0到1。

因此,過程如下:

<code>8位RGB → 標(biāo)準(zhǔn)RGB → 線性RGB → 亮度</code>

一旦我們有了想要比較的兩種顏色的亮度,我們就可以將亮度值代入公式中,得到它們各自顏色之間的對比度。

// getContrast是我們唯一需要直接交互的函數(shù)。
// 其余函數(shù)是中間輔助步驟。
function getContrast(color1, color2) {
  const color1_luminance = getLuminance(color1);
  const color2_luminance = getLuminance(color2);
  const lighterColorLuminance = Math.max(color1_luminance, color2_luminance);
  const darkerColorLuminance = Math.min(color1_luminance, color2_luminance);
  const contrast = (lighterColorLuminance   0.05) / (darkerColorLuminance   0.05);
  return contrast;
}

function getLuminance({r,g,b}) {
  return (0.2126 * getLinearRGB(r)   0.7152 * getLinearRGB(g)   0.0722 * getLinearRGB(b));
}
function getLinearRGB(primaryColor_8bit) {
  // 首先從8位rgb(0-255)轉(zhuǎn)換為標(biāo)準(zhǔn)RGB(0-1)
  const primaryColor_sRGB = convert_8bit_RGB_to_standard_RGB(primaryColor_8bit);

  // 然后從sRGB轉(zhuǎn)換為線性RGB,以便我們可以使用它來計算亮度
  const primaryColor_RGB_linear = convert_standard_RGB_to_linear_RGB(primaryColor_sRGB);
  return primaryColor_RGB_linear;
}
function convert_8bit_RGB_to_standard_RGB(primaryColor_8bit) {
  return primaryColor_8bit / 255;
}
function convert_standard_RGB_to_linear_RGB(primaryColor_sRGB) {
  const primaryColor_linear = primaryColor_sRGB 
<p>現(xiàn)在我們可以計算對比度了,我們需要查看上一步中的圖像,并遍歷每個像素,比較該像素的顏色與前景文本顏色之間的對比度。當(dāng)我們遍歷圖像的像素時,我們將跟蹤到目前為止最差(最低)的對比度,當(dāng)我們到達(dá)循環(huán)的末尾時,我們將知道圖像中對比度最差的顏色。</p>
<pre class="brush:php;toolbar:false">function getWorstContrastColorInImage(textColor, imagePixelColors) {
  let worstContrastColorInImage;
  let worstContrast = Infinity; // 這保證我們不會從太低的值開始
  for (let i = 0; i 
<p></p><h3>步驟3:準(zhǔn)備顏色混合公式來測試疊加不透明度級別</h3>
<p></p><p>現(xiàn)在我們知道了圖像中對比度最差的顏色,下一步是確定疊加層的透明度應(yīng)該有多高,并查看這將如何改變與文本的對比度。</p>
<p></p><p>當(dāng)我第一次實現(xiàn)這一點時,我使用了單獨的畫布來混合顏色并讀取結(jié)果。但是,感謝Ana Tudor關(guān)于透明度的文章,我現(xiàn)在知道有一個方便的公式可以計算將基本顏色與透明疊加層混合后的結(jié)果顏色。</p>
<p></p><p>對于每個顏色通道(紅色、綠色和藍(lán)色),我們將應(yīng)用此公式來獲取混合顏色:</p>
<p>混合顏色 = 基本顏色   (疊加顏色 - 基本顏色) * 疊加不透明度</p>
<p></p><p>因此,在代碼中,這將如下所示:</p>
<pre class="brush:php;toolbar:false">function mixColors(baseColor, overlayColor, overlayOpacity) {
  const mixedColor = {
    r: baseColor.r   (overlayColor.r - baseColor.r) * overlayOpacity,
    g: baseColor.g   (overlayColor.g - baseColor.g) * overlayOpacity,
    b: baseColor.b   (overlayColor.b - baseColor.b) * overlayOpacity,
  }
  return mixedColor;
}

現(xiàn)在我們可以混合顏色了,我們可以測試應(yīng)用疊加不透明度值時的對比度。

function getTextContrastWithImagePlusOverlay({textColor, overlayColor, imagePixelColor, overlayOpacity}) {
  const colorOfImagePixelPlusOverlay = mixColors(imagePixelColor, overlayColor, overlayOpacity);
  const contrast = getContrast(textColor, colorOfImagePixelPlusOverlay);
  return contrast;
}

有了這個,我們就擁有了找到最佳疊加不透明度所需的所有工具!

步驟4:找到達(dá)到對比度目標(biāo)的疊加不透明度

我們可以測試疊加層的不透明度,并查看這將如何影響文本和圖像之間的對比度。我們將嘗試許多不同的不透明度級別,直到我們找到達(dá)到目標(biāo)對比度的值,其中文本比背景亮4.5倍。這聽起來可能很瘋狂,但別擔(dān)心;我們不會隨機猜測。我們將使用二分查找,這是一個讓我們能夠快速縮小可能的答案集直到得到精確結(jié)果的過程。

以下是二分查找的工作原理:

<code>- 在中間猜測。
- 如果猜測過高,我們將消除答案的上半部分。太低了嗎?我們將改為消除下半部分。
- 在新的范圍中間猜測。
- 重復(fù)此過程,直到我們得到一個值。

我碰巧有一個工具可以展示它是如何工作的:

在這種情況下,我們試圖猜測一個介于0和1之間的不透明度值。因此,我們將從中間猜測,測試結(jié)果對比度是太高還是太低,消除一半的選項,然后再次猜測。如果我們將二分查找限制為八次猜測,我們將立即得到一個精確的答案。

在我們開始搜索之前,我們需要一種方法來檢查是否根本需要疊加層。我們根本不需要優(yōu)化我們不需要的疊加層!

```javascript
function isOverlayNecessary(textColor, worstContrastColorInImage, desiredContrast) {
  const contrastWithoutOverlay = getContrast(textColor, worstContrastColorInImage);
  return contrastWithoutOverlay </code>

現(xiàn)在我們可以使用二分查找來查找最佳疊加不透明度:

function findOptimalOverlayOpacity(textColor, overlayColor, worstContrastColorInImage, desiredContrast) {
  // 如果對比度已經(jīng)足夠好,我們不需要疊加層,
  // 因此我們可以跳過其余部分。
  const isOverlayNecessary = isOverlayNecessary(textColor, worstContrastColorInImage, desiredContrast);
  if (!isOverlayNecessary) {
    return 0;
  }

  const opacityGuessRange = {
    lowerBound: 0,
    midpoint: 0.5,
    upperBound: 1,
  };
  let numberOfGuesses = 0;
  const maxGuesses = 8;

  // 如果沒有解決方案,不透明度猜測將接近1,
  // 因此我們可以將其作為上限來檢查無解的情況。
  const opacityLimit = 0.99;

  // 此循環(huán)重復(fù)縮小我們的猜測,直到我們得到結(jié)果
  while (numberOfGuesses  desiredContrast;

    if (isGuessTooLow) {
      opacityGuessRange.lowerBound = currentGuess;
    }
    else if (isGuessTooHigh) {
      opacityGuessRange.upperBound = currentGuess;
    }

    const newMidpoint = ((opacityGuessRange.upperBound - opacityGuessRange.lowerBound) / 2)   opacityGuessRange.lowerBound;
    opacityGuessRange.midpoint = newMidpoint;
  }

  const optimalOpacity = opacityGuessRange.midpoint;
  const hasNoSolution = optimalOpacity > opacityLimit;

  if (hasNoSolution) {
    console.log('No solution'); // 根據(jù)需要處理無解的情況
    return opacityLimit;
  }
  return optimalOpacity;
}

實驗完成后,我們現(xiàn)在確切地知道疊加層的透明度需要多高才能使文本可讀,而不會隱藏過多的背景圖像。

我們做到了!

改進(jìn)和局限性

我們介紹的方法只有在文本顏色和疊加顏色本身具有足夠的對比度時才有效。例如,如果您選擇與疊加層相同的文本顏色,除非圖像根本不需要疊加層,否則將不會有最佳解決方案。

此外,即使對比度在數(shù)學(xué)上是可以接受的,但這并不總是保證它看起來很棒。對于具有淺色疊加層和繁忙背景圖像的深色文本尤其如此。圖像的各個部分可能會分散對文本的注意力,即使對比度在數(shù)值上很好,也可能難以閱讀。這就是為什么流行的建議是在深色背景上使用淺色文本。

我們也沒有考慮像素的位置或每種顏色的像素數(shù)量。這樣做的一個缺點是,角落中的像素可能會對結(jié)果產(chǎn)生過大的影響。但是,好處是,我們不必?fù)?dān)心圖像的顏色是如何分布的或文本在哪里,因為只要我們處理了對比度最少的地方,我們就可以在其他任何地方都安全。

我在此過程中學(xué)習(xí)到了一些東西

在這個實驗之后,我有一些收獲,我想與你們分享:

<code>- **明確目標(biāo)非常有幫助!**我們從一個模糊的目標(biāo)開始,即想要在圖像上顯示可讀的文本,最終得到了一個我們可以努力達(dá)到的特定對比度級別。
- **明確術(shù)語非常重要。**例如,標(biāo)準(zhǔn)RGB并非我所期望的。我了解到,我認(rèn)為的“常規(guī)”RGB(0到255)正式稱為8位RGB。此外,我認(rèn)為我研究的方程式中的“L”表示“亮度”,但它實際上表示“亮度”,這不能與“光度”混淆。澄清術(shù)語有助于我們編寫代碼以及討論最終結(jié)果。
- **復(fù)雜并不意味著無法解決。**聽起來很困難的問題可以分解成更小、更容易管理的部分。
- **當(dāng)你走過這條路時,你會發(fā)現(xiàn)捷徑。**對于白色文本在黑色透明疊加層上的常見情況,您永遠(yuǎn)不需要超過0.54的不透明度即可達(dá)到WCAG AA級可讀性。

### 總結(jié)…

您現(xiàn)在有了一種方法可以在背景圖像上使文本可讀,而不會犧牲過多的圖像。如果您已經(jīng)讀到這里,我希望我已經(jīng)能夠讓您大致了解其工作原理。

我最初開始這個項目是因為我看到(并制作了)太多網(wǎng)站橫幅,其中文本在背景圖像上難以閱讀,或者背景圖像被疊加層過度遮擋。我想做些什么,我想給其他人提供一種同樣的方法。我寫這篇文章是為了希望你們能夠更好地理解網(wǎng)絡(luò)上的可讀性。我希望你們也學(xué)習(xí)了一些很酷的canvas技巧。

如果您在可讀性或canvas方面做了一些有趣的事情,我很樂意在評論中聽到您的想法!</code>

以上是釘在光文和背景圖像之間的完美對比度的詳細(xì)內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

什么是'渲染障礙CSS”? 什么是'渲染障礙CSS”? Jun 24, 2025 am 12:42 AM

CSS會阻塞頁面渲染是因為瀏覽器默認(rèn)將內(nèi)聯(lián)和外部CSS視為關(guān)鍵資源,尤其是使用引入的樣式表、頭部大量內(nèi)聯(lián)CSS以及未優(yōu)化的媒體查詢樣式。1.提取關(guān)鍵CSS并內(nèi)嵌至HTML;2.延遲加載非關(guān)鍵CSS通過JavaScript;3.使用media屬性優(yōu)化加載如打印樣式;4.壓縮合并CSS減少請求。建議使用工具提取關(guān)鍵CSS,結(jié)合rel="preload"異步加載,合理使用media延遲加載,避免過度拆分與復(fù)雜腳本控制。

外部與內(nèi)部CSS:最好的方法是什么? 外部與內(nèi)部CSS:最好的方法是什么? Jun 20, 2025 am 12:45 AM

thebestapphachforcssdepprodsontheproject'sspefificneeds.forlargerprojects,externalcsSissBetterDuoSmaintoMaintainability andReusability; forsMallerProjectsorsingle-pageApplications,InternaltCsmightBemoresobleable.InternalCsmightBemorese.it.it'sclucialtobalancepopryseceneceenceprodrenceprodrenceNeed

我的CSS必須在較低的情況下嗎? 我的CSS必須在較低的情況下嗎? Jun 19, 2025 am 12:29 AM

否,CSSDOESNOTHAVETOBEINLOWERCASE.CHOMENDENS,使用flowercaseisrecommondendendending:1)一致性和可讀性,2)避免使用促進(jìn)性技術(shù),3)潛在的Performent FormanceBenefits,以及4)RightCollaboraboraboraboraboraboraboraboraboraboraboraboraboraboraboraboraborationWithInteams。

CSS案例靈敏度:了解重要的 CSS案例靈敏度:了解重要的 Jun 20, 2025 am 12:09 AM

cssismostlycaseminemintiment,buturlsandfontfamilynamesarecase敏感。1)屬性和valueslikeColor:紅色; prenotcase-sensive.2)urlsmustmustmatchtheserver'server'scase,例如

什么是AutoPrefixer,它如何工作? 什么是AutoPrefixer,它如何工作? Jul 02, 2025 am 01:15 AM

Autoprefixer是一個根據(jù)目標(biāo)瀏覽器范圍自動為CSS屬性添加廠商前綴的工具。1.它解決了手動維護(hù)前綴易出錯的問題;2.通過PostCSS插件形式工作,解析CSS、分析需加前綴的屬性、依配置生成代碼;3.使用步驟包括安裝插件、設(shè)置browserslist、在構(gòu)建流程中啟用;4.注意事項有不手動加前綴、保持配置更新、非所有屬性都加前綴、建議配合預(yù)處理器使用。

什么是CSS計數(shù)器? 什么是CSS計數(shù)器? Jun 19, 2025 am 12:34 AM

csscounterscanautomationallymentermentermentections和lists.1)usecounter-ensettoInitializize,反插入式發(fā)芽,andcounter()orcounters()

CSS:何時重要(何時不)? CSS:何時重要(何時不)? Jun 19, 2025 am 12:27 AM

在CSS中,選擇器和屬性名不區(qū)分大小寫,而值、命名顏色、URL和自定義屬性則區(qū)分大小寫。1.選擇器和屬性名不區(qū)分大小寫,例如background-color和Background-Color相同。2.值中的十六進(jìn)制顏色不區(qū)分大小寫,但命名顏色區(qū)分大小寫,如red有效而Red無效。3.URL區(qū)分大小寫,可能導(dǎo)致文件加載問題。4.自定義屬性(變量)區(qū)分大小寫,使用時需注意大小寫一致。

什么是圓錐級函數(shù)? 什么是圓錐級函數(shù)? Jul 01, 2025 am 01:16 AM

theconic-Gradient()functionIncsscreatesCircularGradientsThatRotateColorStopSaroundAcentralPoint.1.IsidealForPieCharts,ProgressIndicators,colordichers,colorwheels和decorativeBackgrounds.2.itworksbysbysbysbydefindefingincolordefingincolorstopsatspecificains off.

See all articles