iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 16
2
Modern Web

用 Javascript 當個影像魔術師系列 第 16

Day 16 - CSS 原生濾鏡

原生濾鏡

前面都在提說如何用 JaveScript 去改變圖像中的每個像素值來達成我們想要的效果,但其實在原生 CSS 中就有提供一些屬性來提供效果,今天我們就來看一下吧!

通過 MDN,目前支援的濾鏡有以下幾種

屬性 範例 (參數)
blur 5px (或其他CSS長度值)
brightness 0.5 或 50% (百分比或小數)
contrast 0.5 或 50% (百分比或小數)
drop-shadow 10px 10px(水平模糊、垂直模糊)
grayscale 0.5 或 50% (百分比或小數)
hue-rotate 0 deg ~ 360 deg
invert 0.5 或 50% (百分比或小數)
opacity 0.5 或 50% (百分比或小數)
saturate 0.5 或 50% (百分比或小數)
sepia 0.5 或 50% (百分比或小數)

在裡面也應該會看到好幾種都是我們先前做過的範例,那直接將全部一起顯示出來吧!

這次讀取檔案的方式我們採用上篇提到的 Blob 形式,一樣定義一個 input 當作輸入,並觸發這個方法

 getData(event) {
        const file = event.target.files[0]
        this.blobSrc = URL.createObjectURL(file)
      }

createObjectURL 除了 dataUrl 做為輸入之外,也可以使用 file 的形式

接著我們定義一連串的濾鏡陣列

  data() {
      return {
        blobSrc: '',
        cssFilterList: [ {
            class: 'blur',
            value: '(10px)'
          },{
            class: 'brightness',
            value: '(150%)'
          },{
            class: 'contrast',
            value: '(150%)'
          },{
            class: 'drop-shadow',
            value: '(10px 10px)'
          },{
            class: 'grayscale',
            value: '(50%)'
          },{
            class: 'hue-rotate',
            value: '(180deg)'
          },{
            class: 'invert',
            value: '(100%)'
          }, {
            class: 'opacity',
            value: '(50%)'
          },{
            class: 'saturate',
            value: '(150%)'
          },{
            class: 'sepia',
            value: '(150%)'
          }
        ]
      }
    }

直接透過 v-for 把所有都顯示出來

    <figure v-for="cssFilter in cssFilterList">
      <figcaption>
        CSS Filter : {{ cssFilter.class }} {{ cssFilter.value }}
      </figcaption>
      <img
        :src="blobSrc"
        :style="{filter: `${cssFilter.class}${cssFilter.value}`}"
      />
    </figure>

這樣就輕鬆把所有的濾鏡都加上去囉

而 filter 也可以用複合的方式使用,例如

filter: blur(5px) grayscale(1);

這樣就可以將兩種效果混合在一起,而大家在使用 Instgram 的時候除了可以手動調特定參數之外,通常都會有許多的現成濾鏡可以直接套用,其實原理跟調整是一樣的,只是幫你設定好了某些預設參數,而有一個套件 CSSgram 也提供了類似的功能,只要使用特定的 class 就可以有獨特的相片風格。

一樣照著上面的做法,我們直接在 class 裡面加入相對應的名稱就好

  cssGramList: [
          '_1977',
          'aden',
          'amaro',
          'brannan',
          'brooklyn',
          'clarendon',
          'gingham',
          'hudson',
          'inkwell',
          'kelvin',
          'lark',
          'lofi'
        ]

html 裡面使用

<figure v-for="cssFilter in cssGramList">
      <figcaption>CSSGram Filter : {{ cssFilter }}</figcaption>
      <img :src="blobSrc" :class="[cssFilter]" />
</figure>

就可以很輕鬆的做出熱門的相片效果囉

其實觀看原始程式碼會發現其實就是將原生的屬性集合在一起調整一下就可以做到效果,所以大家也可以輕鬆的做出自己喜歡的濾鏡風格唷~

// 其中一個濾鏡的部分程式碼
filter: contrast(1.1) brightness(1.1) saturate(1.3)

效果選擇

既然我們可以用原生的屬性做到濾鏡效果,也可以透過 Javascript 修改像素達成類似的效果,那我們應該要選擇哪一個呢?小整理一下優劣

  • Javascript
    • 優點
      • 定制性強,可客制各種調整
    • 缺點
      • 程式複雜度提升
      • 效率較差
  • CSS
    • 優點
      • 簡單好用
      • 效率較優
    • 缺點
      • 屬性無法客制調整

其實如果原生的效果就可以滿足需求的話,絕對是沒有必要使用 Javascript,至於效率的問題 參考到了 這篇文章,看起來手動使用 Javascript 處於最糟的情況,雖然也是不太意外,因為畢竟是需要對整個像素跑完做處理,但心理蠻好奇原生的屬性是不是有用 GPU 做加速或者是說可以看到原始實作,找來找去看到 這個,看起來是有機會經過 GPU 加速的。

比較效率文章是用 Javascript 做灰階效果然後做比較,但畢竟不知道原生是如何實現的,所以直接這樣子比我想也是不太公平啦,不過無論如何,原生的是最有機會被瀏覽器優化的,如果原生效果就可以接受的話一定是選擇原生的囉!

小結

DEMO

今天介紹在班公錯遇到的牛,牛在印度真的是滿地跑不誇張,直接在道路上橫衝直撞,生在印度的牛挺幸運的呢!

今天介紹到了原生的濾鏡,但說實在話使用的機會似乎不太多,畢竟如果真的是要做跟影像編輯相關的網頁軟體,應該是不可能使用原生的方法,畢竟可控性太低了,但如果下次有要對圖片做一些簡單的特效處理的時候別忘了這些功能唷!


上一篇
Day 15 - 圖片保存 Part 2 & 小結
下一篇
Day 17 - Canvas 影片播放
系列文
用 Javascript 當個影像魔術師30

尚未有邦友留言

立即登入留言