不久前我要找一個可以在個人項目中進行使用的圖形操作庫。我所找到最理想的一個庫就是 CamanJS 了, 它是一個基于Javascript的canvas操作庫。
你可能會想問既然CSS已經有現成的功能可以支持基礎的圖像操作了,為什么我們還會想要為此使用一個像這樣的 Javascript 庫呢。好吧,除了有瀏覽器的支持,使用 CamanJS 有許多的好處。它為我們操作圖像提供了更多的過濾器和選項。你可以在你的圖像中創建高級過濾器,進而控制其中的每一個像素。你可以使用其內置的混合模式和圖層系統。而它也能讓你進行圖像的跨域操作,并可以對操作產生的圖像進行保存。
現在,就讓我們來開始探索 CamanJS 所提供的特性吧!
引入必要的文件
要開始使用 CamanJS,需要簡單的將這個庫引入到你的頁面中. 我所引用的這個最小化的 CDN 版本除了核心功能之外,所有的插件都被組合到了一個文件中:
- <script src="https://cdnjs.cloudflare.com/ajax/libs/camanjs/4.1.2/caman.full.min.js">
- </script>
從版本3到4,CamanJS 函數的語法發生了一點小小的改變。因此請確保在跟隨這個教程進行實際操作時,你所引入的版本在4以上。
通過HTML屬性進行圖像操作
CamanJS 可以被用來利用 data-caman 屬性對圖像進行操作。如下代碼向你展示了如何將一個亮度為“10”的過濾器,以及一個對比度為“30”的過濾器應用到一張圖片上:
- <img data-caman="brightness(10) contrast(30)"
- src="http://www.argcandargv.com/skin/default/image/lazy.gif" class="lazy" original="yourimage.jpg" alt="CamanJS Javascript庫 Web頁面 圖像處理">
其它可以用類似的語法加以運用的 18 個過濾器也被打包到了這個庫里面。例如:
- <img data-caman="love() hazyDays()"
- src="http://www.argcandargv.com/skin/default/image/lazy.gif" class="lazy" original="yourimage.jpg" alt="CamanJS Javascript庫 Web頁面 圖像處理">
通過 Javascript 操作圖像
你也可以選擇通過寫幾行 Javascript 來操作一張圖像。使用 Javascript 操作的結果跟使用 data-caman 屬性所產生的結果是一樣的。
- Caman('#your-image-id', function () {
- this.brightness(40);
- this.contrast(-10);
- this.sinCity();
- this.render();
- });
實現一個圖像編輯器中的控件
過濾器其實不需要做過多的調整就可以用在按鈕點擊的觸發上. 一些像 vintage(),lomo(), 以及 sinCity() 這樣的過濾器不需要參數。其它像 contrast() 和 noise() 過濾器則需要一個整型值作為參數。這個值決定了過濾器的強度。
復雜的過濾器如 tiltShift(),posterize(), 以及 vignette() 則需要不止一個參數。下面的代碼塊演示了如果用3個按鈕進行3種過濾器操作。針對其它的過濾器也可以像這樣寫代碼。下面是HTML:
- <canvas id="canvas"></canvas>
- <button id="vintagebtn">Vintage</button>
- <button id="noisebtn">Noise</button>
- <button id="tiltshiftbtn">Tilt Shift</button>
下面是將過濾器應用到按鈕點擊上的 Javascript/jQuery 代碼:
- var vintage = $('#vintagebtn');
- var noise = $('#noisebtn');
- var tiltshift = $('#tiltshiftbtn');
- vintage.on('click', function(e) {
- Caman('#canvas', img, function() {
- this.vintage();
- this.render();
- });
- });
- noise.on('click', function(e) {
- Caman('#canvas', img, function() {
- this.noise(10);
- this.render();
- });
- });
- tiltshift.on('click', function(e) {
- Caman('#canvas', img, function() {
- this.tiltShift({
- angle: 90,
- focusWidth: 600
- }).render();
- });
- });
tiltshift() 也接受另外的像 startRadius 和 radius 這樣的參數, Factor.vignette() 有 size 和 strength 這兩個參數,你可以參考 CamanJS 文檔 來深入理解所有的過濾器。
實現滑塊控件
像 brightness, contrast, 和 hue 這樣需要相對更精確控制取值的過濾器,使用范圍值輸入滑塊就可以很好的工作。你將會看到,實現滑塊控件只比按鈕控制有稍微的不同. 你可以使用下面的HTML來創建范圍滑塊:
- <form id="silderInput">
- <label for="hue">Hue</label>
- <input id="hue" name="hue" type="range" min="0" max="300" value="0">
- <label for="contrast">Contrast</label>
- <input id="contrast" name="contrast" type="range" min="-20" max="20" value="0">
- </form>
下面的jQuery代碼塊處理所有了操作:
- $('input[type=range]').change(applyFilters);
- function applyFilters() {
- var hue = parseInt($('#hue').val());
- var cntrst = parseInt($('#contrast').val());
- Caman('#canvas', 'image.jpg', function() {
- this.revert(false);
- this.hue(hue);
- this.contrast(cntrst);
- this.render();
- });
- }
applyFilters() 函數在輸入范圍滑塊的值發生改變時都會被調用。這個函數用對應變量存儲了所有范圍滑塊的值。為了對圖像進行編輯,這些值隨后會被作為參數傳遞到對應的過濾器。
每次我都會在應用這些過濾器時調用this.revet(false),來時的canvas回到其原來的狀態。使用revert可以確保過濾器所操作的是原來的圖像,而它們的效果不會是混亂的. 傳入的false參數值可以避免在圖像還原過程中的間斷閃爍。
值得一提的另外一個細節是即使我一次只改變了它們其中的一個值,我也會將所有的過濾器應用一遍。 這是因為用戶不會希望在他們正調整色相和亮度值時看到對比度被重置。