利用CSS改變圖片顏色的100種方法!

RNG牛逼發表於2019-02-16

前言

“說到對圖片進行處理,我們經常會想到PhotoShop這類的影像處理工具。作為前端開發者,我們經常會需要處理一些特效,例如根據不同的狀態,讓圖示顯示不同的顏色。或者是hover的時候,對圖片的對比度,陰影進行處理。”

圖片描述

你以為這些是經過PS軟體處理出來的?不不不,純粹的是用css寫出來的,很神奇把。

強大的 CSS:filter

CSS濾鏡(filter)屬提供的圖形特效,像模糊,銳化或元素變色。過濾器通常被用於調整圖片,背景和邊界的渲染。 MDN

CSS標準裡包含了一些已實現預定義效果的函式。

filter: none        
    | blur() 
    | brightness() 
    | contrast() 
    | drop-shadow() 
    | grayscale() 
    | hue-rotate() 
    | invert() 
    | opacity() 
    | saturate() 
    | sepia() 
    | url();
<!--html-->
<img src="https://note.youdao.com/yws/res/237/WEBRESOURCE7e77df2551fe1a1db1b9d91f4d518917" alt="原圖">

圖片描述

filter: none

沒有任何效果,預設filter就為none

filter:blur( <length> ) 高斯模糊

給影像一個高斯模糊效果,length值越大,影像越模糊

我們來嘗試一下

img {
    filter:blur(2px);;
}

圖片描述

brightness(%) 線性乘法

可以讓圖片看起來更亮或者更暗

img {
    filter:brightness(70%);
}

圖片描述

contrast(%) 對比度

調整影像的對比度。

img {
    filter:contrast(50%);
}

圖片描述

drop-shadow(h-shadow v-shadow blur spread color)

給影像設定一個陰影效果。陰影是合成在影像下面,可以有模糊度的,可以以特定顏色畫出的遮罩圖的偏移版本。 函式接受<shadow>(在CSS3背景中定義)型別的值,除了”inset”關鍵字是不允許的。該函式與已有的box-shadow box-shadow屬性很相似;不同之處在於,通過濾鏡,一些瀏覽器為了更好的效能會提供硬體加速

利用這個方案,我們其實改變類似於一些圖示的顏色,比如黑色的圖示變成藍色的圖示。

PNG格式小圖示的CSS任意顏色賦色技術

img {
    filter: drop-shadow(705px 0 0 #ccc);
}

在這裡,我們將圖片投影形成一個同等大小的灰色區域。
圖片描述

hue-rotate(deg) 色相旋轉

img {
    filter:hue-rotate(70deg);
}

看,我的小姐姐變成了阿凡達!
圖片描述

invert(%) 反轉

這個函式的作用是反轉輸入影像,有點像曝光的效果

img {
    filter:invert(100%)
}

圖片描述

grayscale(%) 將影像轉換為灰度影像

這個效果可以將圖片做舊,有一種時代滄桑感。喜歡古風的人一定會喜歡上這個效果的

img {
    filter:grayscale(80%);
}

圖片描述

還有一種用法是有的時候需要將全站變成灰色,如紀念日或者哀悼日的時候。

圖片描述
可以這樣設定

*{
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
    -o-filter: grayscale(100%);
}

sepia(%) 將影像轉換為深褐色

下面給我的小姐姐一個暖暖的色調。

img {
    filter:sepia(50%)
}

圖片描述

大家是不是發現我並沒有把url()方法寫到這上面來

沒錯,因為我想把這個內容放到最後來說,filter:url()就是css濾鏡改變圖片的終極方法。CSS:filter可以匯入一個svg濾鏡,作為他自己的濾鏡。

終極變色解決方案! filter:url();

為什麼說filter:url()是圖片變色的終極解決方案呢,請容我慢慢道來。

我們先科普一下PS的工作原理,我們都知道網頁是有三原色的R(紅) G(綠) B(藍),常見的RGBA還包括一個opicity值,而opcity值是根據alpha通道計算出來的。也就是說,我們見到的網頁的每一個畫素點都是由紅藍綠再加alpha四個通道組成,每一個通道我們稱之為色板,PS中的8位板的意思就是2的八次方256,意思就是每一個通道的取值範圍都是(0-255) SVG 研究之路 (11) – filter:feColorMatrix

如果我們可以改變每個通道的值是不是就能完美的得到我們想要的任意顏色了呢,原理上,我們可以像ps那樣利用svg濾鏡得到任何我們想要的影像,不僅僅是變色。我們甚至可以憑空生成一幅影像。

svg feColorMatrix大法好

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <filter id="change">
                <feColorMatrix type="matrix" values="
                0 0 0 0 0.55
                0 0 0 0 0.23 
                0 0 0 0 0 
                0 0 0 0 1" />
        </filter>
    </defs>
</svg>
<img src="https://note.youdao.com/yws/res/237/WEBRESOURCE7e77df2551fe1a1db1b9d91f4d518917" alt="">
img {
    filter:url(#change);
}

通過單通道我們可以將圖片變成單一的顏色
圖片描述

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <filter id="change">
               <feColorMatrix values="3 -1 -1 0 0
                       -1 3 -1 0 0
                       -1 -1 3 0 0
                       0 0 0 1 0" />
        </filter>
    </defs>
</svg>

通過雙通道我們可以的到一些非常炫酷的PS效果

圖片描述

當然,在這裡,只是舉個例子,通過配置矩陣中的值,我們可以配置每一個畫素點的值按照我們定義的規則顯示

我們在這裡詳細講一下feColorMatrix 矩陣的計算方式

圖片描述

其中Rin Gin Bin a(alpha) 為原始圖片中每個畫素點的rgba值

通過矩陣計算,得到的Rout Gout Bout Aout就是最終顯示出來的rgba值。

將圖片轉為單色 拿棕色rgba(140,59,0,1)作為例子

根據上面的公式,我們可以簡化一些計算,同一行中,只設定一個通道的值,其他通道為0

不難得出矩陣

0 0 0 0 目標值R
0 0 0 0 目標值G
0 0 0 0 目標值B
0 0 0 0 1

根據規則,只需要計算,255/想要顯示的顏色對應通道 = 目標值

我們想要的棕色rgba(140,59,0,1) 換算成色板 rgba 為 140 59 0 255

可以算出目標值

0 0 0 0 0.55
0 0 0 0 0.23
0 0 0 0 0 
0 0 0 0 1

多通道設定出炫酷的效果來

就如同之前我們看到的雙通道形成的炫酷圖片一般

我們今天要把圖片的飽和度提高,該怎麼做呢?首先當然是想想飽和度的成因,就是紅的越紅,藍的越藍,綠的越綠,由這個成因出發,我們的矩陣就可以寫成下面的樣子,看到矩陣當中出現了 3 和 -1,一定會很那悶這是怎麼來的,箇中原理其實很容易理解,讓我們假設某一個畫素的 RGB 分別是 (200/255),(100/255),(50/255),呈現的應該是有點暗沉的橘色,經過矩陣的換算,R 變成了 200/255×3-100/255-50/255= 1.76, G 變成 200/255x(-1)+100/255*3-50/255=0.2,B 變成 200x(-1)+100x(-1)+50×3=-0.59,因此 RGB 轉換後就是:200×1.76,100×0.2,50x-0.5。SVG 研究之路 (11) – filter:feColorMatrix

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <filter id="change">
               <feColorMatrix values="3 -1 -1 0 0
                       -1 3 -1 0 0
                       -1 -1 3 0 0
                       0 0 0 1 0" />
        </filter>
    </defs>
</svg>

其他方案

除了feColorMatrix svg濾鏡還有很多的方法可以定義濾鏡,他們同樣可以作用到圖片上。由於篇幅限制,這裡就不詳細展開了

總結

  • css3提供了filter這個屬性,使得通過前端技術實現更多炫酷的特效成為了可能
  • 依賴於svg的濾鏡,我們可以實現複雜的濾鏡效果

注意

  • css:filter與ie上的filter並不是相同的概念
  • css:filter在不同的瀏覽器上相容性不一樣,您在使用的時候需要注意瀏覽器的相容性

圖片描述

參考文獻

寫在最後

本次原始碼我已經放在了codePen上 https://codepen.io/nanhupatar… 歡迎檢視

文章難免會有疏漏,希望大家能夠指正批評。如果您覺得本文對您有幫助,請點個贊支援作者。

最後,安利我們的公眾號:前端指南。致力於前端技術分享,精品文章,深度好文,同時也歡迎您給我們投稿,本公眾號使用者留存率95%哦,對了,更新時間是每天早上六點

圖片描述

轉載請註明出處與作者,原創不易,歡迎轉載

相關文章