Canvas 真的是一個神奇的東西,不僅能夠繪製各種圖形、文字和點陣圖,還能夠對點陣圖進行複雜的像素運算和處理。因此像濾鏡這些東西,其實Canvas 也可以來實現。接下來,是見證奇蹟的時刻。
首先,我們需要有一個Canvas 容器,例如:
<canvas id=myCanvas width=800 height=800></canvas>
接下來,我們需要將使用Canvas 來繪製一張圖片:
var myCanvas = document.getElementById(myCanvas);var ctx = myCanvas.getContext(2d);var img = new Image();img.src = ./images/1526010092000.jpg;//on 自我連結圖片連結 = (e) => {ctx.drawImage(img, 0, 0, 800, 800);// 第一個800表示繪製圖片的寬,第二個800表示繪製圖片的高}Canvas首次繪製的效果
再接下來就是對圖片的像素進行一些操作。而要實現這樣的操作,首先需要從Canvas 獲取到圖片的像素信息,而獲取這些信息可以透過getImageData()來實現。
// ... 省略前面程式碼img.onload = (e) => {// ... 省略前面程式碼img = ctx.getImageData(0, 0, 800, 800);// 取得包含每個像素點顏色的位元組資料}由於圖片的大小為800 * 800,因為要對像素點進行遍歷,以獲得每一個像素點的紅、綠、藍色值。因此:
// ... 省略前面程式碼img.onload = (e) => {// ... 省略前面程式碼var pixelLen = 800 * 800; // 取得像素個數for(var i = 0; i < pixelLen * 4; i += 4) { var redC = img.data[i], // 第一個位元組單位代表紅色greenC = img.data[i + 1], //第二個位元組單位代表綠色blueC = img.data[i + 2], // 第三個位元組單位代表藍色alpha = img.data[i + 3]; // 第四個位元組單位代表透明度}}透過上方循環,我們取得了包含在圖片資料中的每個像素點的具體色值;需要注意的一點是,每一個像素點的資料不是一位,而是相鄰的四位,分別代表了該點的紅、綠、藍和透明值。因此,實際上位圖位元組資料的數組長度等於像素點個數乘以4,在for 迴圈中我們也針對此特性進行了對應處理。
將每一點的紅、綠、藍值進行平均,然後再將生成的平均值相同地賦予該像素點的紅、綠、藍值,就能形成灰階效果,最後透過putImageData()方法來重新繪製圖片即可,程式碼如下:
// ... 省略前面程式碼img.onload = (e) => {// ... 省略前面程式碼for(var i = 0; i < pixelLen * 4; i += 4) { // ...省略前面程式碼var grey = parseInt((redC + greenC + blueC) / 3); // 平均後取得灰階值img.data[i] = grey; // 改變紅色值img.data[i + 1] = grey; // 改變綠色值img.data[i + 2] = grey; // 改變藍色值} ctx.putImageData(img, 0, 0, 800, 800); // 重新繪製圖片}此時,則會形成灰階效果,如下圖
Canvas第二次繪製圖片-灰階效果
透明度的控制只需要修改第四個位元組單位對應的數值即可,該數值的範圍為0~256,0代表完全透明,256代表完成不透明。例如:
// ... 省略前面程式碼img.onload = (e) => {// ... 省略前面程式碼for(var i = 0; i < pixelLen * 4; i += 4) { // ...省略前面程式碼img.data[i + 3] = 128;// 透明度50% } // ... 省略前面程式碼}Canvas第三次繪製效果-增加透明度
由此,透過控制圖片中每個像素4個資料的值,即可達到濾鏡的效果,是不是so easy!
參考文獻:
《HTML5 基礎、核心技術與前沿案例》 劉歡編著
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。