高斯模糊濾鏡效果解析
前言
這個東西呢不管看起來,聽起來都很高大上哈.鄙人比較懶,知道有這么個東西,卻一直沒去研究.感嘆技術日新月異,有時候覺得自己掉隊好遠了.這不項目中便遇到了使用這家伙的情況.這次需要做一個音樂類app,需要有毛玻璃的高大上效果.這個效果在眾多音樂app中非常常見,也確實非常漂亮.但在網頁端見得比較少.大概是兼容性和性能問題吧(強烈吐槽性能).也沒辦法,有需求就得想辦法去實現是不是,不過最討厭跟那群UE,PM撕逼.如果對她們說這個東西很麻煩,不好實現.然后她們一副哥哥你一定可以的!!花癡表情強行綁架了我.哎,誰讓我是程序員呢. 其實吧我自己也挺想去實現這個東西的。默默的給自己打了一針雞血便投入無盡的搜尋,學習中.
css3-filter
搜索一番,找到這個屬性filter:blur(5px)。趕快去實現一把。
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="content-type" content="text/html; charset=utf-8">
5 <title></title>
6 <style>
7 .d1{
8 background-image:url('./lp.png');
9 background-size:cover;
10 -webkit-filter:blur(10px);
11 filter:blur(10px);
12 width:300px;
13 height:300px;
14 }
15 </style>
16 </head>
17 <body>
18
19 <div class="d1"></div>
20 </body>
21 </html>
咳咳, 獻上一個萌妹子.實在找不到圖片了.O(∩_∩)O哈哈~
blur的效果就是虛化圖片.值越大虛化得越厲害.
瞬間高大上了有木有!!
....
....
....
然而事情并沒有這么簡單.濾鏡算法是對圖片的像素點做處理,也就是說你需要設置一張背景圖.當前元素設置濾鏡屬性后,元素里面的內容也會被影響.就拿上面的例子來說,如果元素里面有文字的話,那么文字也看不見了.聰明的你肯定會想到再疊一層不就完了嘛.事實情況也確實如此(這不是廢話么...)讓我們來看下
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title></title>
<style>
.wrap{
position:relative;
width:300px;
height:300px;
line-height:300px;
text-align:center;
}
.d1{
background-image:url('./lp.png');
background-size:cover;
-webkit-filter:blur(10px);
filter:blur(10px);
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:-1;
}
</style>
</head>
<body>
<div class="wrap">
<div class="d1"></div>
<div class="content">我愛你老婆</div>
</div>
</body>
</html>
View Code
完美!
.....
.....
.....
然而事情并沒有這么簡單!
歌詞多是用白色字體,毛玻璃還是太亮了,容易混淆. 嘿嘿,其實也簡單,再加上一點背景透明度就好啦.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title></title>
<style>
.wrap{
position:relative;
width:300px;
height:300px;
}
.d1{
background-image:url('./lp.png');
background-size:cover;
-webkit-filter:blur(10px);
filter:blur(10px);
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:-1;
}
.content{
width:100%;
height:100%;
line-height:300px;
color:#fff;
text-align:center;
background-color:rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<div class="wrap">
<div class="d1"></div>
<div class="content">我愛你老婆</div>
</div>
</body>
</html>
View Code
看這下是不是好多啦. 恩比較有玻璃質感了.其實吧,還有個坑爹的問題, 加了濾鏡blur的元素就變成透明的了 ,雖然有背景圖也還是透明的.所以在需要毛玻璃覆蓋底層的情況下,得再疊一層,添加一個背景色.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title></title>
<style>
.wrap{
position:relative;
width:300px;
height:300px;
}
.filter{
background-image:url('./lp.png');
background-size:cover;
-webkit-filter:blur(10px);
filter:blur(10px);
position: absolute;
top:0;
left:0;
width:100%;
height:100%;
z-index:-1;
}
.filter-bg{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:#333;
z-index:-2;
}
.content{
width:100%;
height:100%;
line-height:300px;
color:#fff;
text-align:center;
background-color:rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<div class="wrap">
<div class="filter-bg"></div>
<div class="filter"></div>
<div class="content">我愛你老婆</div>
</div>
</body>
</html>
View Code
咱們可以隱約的發現, 在圖片的四周模糊效果不是很好,這種情況在blur的值越大的時候越明顯 ,趨勢是模糊區域向圖像中顏色明顯的地方靠近,邊緣地方就顯得透明,甚至貌似沒有模糊.建議blur的值設置在30以下.
似乎問題就這么解決了!!
真的解決了?!
真的?
svg-<filter>
我興奮的,天真的以為事情就這么完了,然而當我附上動畫后,讓毛玻璃動起來時,整個人都崩潰了. fuck! 哥才買的6s玫瑰金,卡得跟屎一樣.當然補充下前提條件,是在播放音樂的時候拖動頁面,頁面元素數量一般.但不至于播放個音樂拖垮了整個頁面性能吧.二愣子的我拖著電腦就去找pm了,你看,就是你要做這種效果,卡得跟方便面一樣一條一條的.搞不定,砍需求!
pm礙于我憤怒的表情,打起了太極.你先冷靜冷靜.什么事兒都好商量.你要不喝點兒飲料?
我當然接受了(你們不要用異樣的眼光看著我). 喝著飲料平靜了下心情,這事兒吧總得解決.和pm鬼扯了半天還是覺得要保留這個效果,不然做了那么久就白費了.況且一個好的工程師(注意我沒有用程序員!)就得迎難而上啊,創造力和解決問題的能力才是工程師們的價值所在.首先還是得定位問題,為了確定是filter屬性的鍋,我把濾鏡層給刪掉,臥槽絲滑般流暢.看來這屬性真是性能堪憂啊.那怎么辦呢,我最終還是抱向了google的大腿.一番搜索,果然不負眾望.原來除了css3之外,svg和canvas也是可以實現濾鏡效果的.我試了下svg,效果真是好得出奇.很流暢.將我們剛才的filter層替換為svg實現
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
baseProfile="full">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="10" />
</filter>
</defs>
<image xlink:href="./mm.jpg" x="0" y="0" height="200" width="200" filter="url(#blur)"/>
</svg>
View Code <filter>標簽用來描述濾鏡,其id屬性唯一標識一個濾鏡.<filter>標簽必須寫在<defs>標簽內.<defs>標簽是對特殊效果進行描述.
最終效果不卡.我猜測應該是實現機制不同,svg添加上濾鏡后就會把它當成一個圖片來處理,不會重復消耗cpu計算.而css3的filter屬性應該是在滾動的時候會動態計算,在做一些比較復雜的效果時候,卡頓就很明顯.
使用svg的濾鏡依然會使得svg層變得透明,在不希望透明的時候記得添加一層背景色.
兼容性對比
咱們再來對比一下兼容性,可見svg稍好,在安卓上都是4.4才支持.
兩種方式的其他濾鏡方法沒用過,似乎也不太常用,也不多說了,網上都能查到.
總結
- css3濾鏡方便,性能不好,適合做靜止的簡單效果
- svg濾鏡性能好,適合做多層運動
- css3濾鏡需要添加背景圖,svg濾鏡背景可以是畫出來的
- css3和svg的高斯模糊濾鏡都會使得該層變得透明
- 高斯模糊在圖片的邊緣效果不太好,可以放大圖片width=105%
- 兼容性二者差不多,svg稍好
參考資料: