高斯模糊濾鏡效果解析

jopen 10年前發布 | 18K 次閱讀 HTML SVG 前端技術

前言

這個東西呢不管看起來,聽起來都很高大上哈.鄙人比較懶,知道有這么個東西,卻一直沒去研究.感嘆技術日新月異,有時候覺得自己掉隊好遠了.這不項目中便遇到了使用這家伙的情況.這次需要做一個音樂類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稍好

參考資料:

來自: http://www.cnblogs.com/fly-snow/p/5131052.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!