2014年11月12日 星期三

HTML5 Canvas的影像處理

  還記得在前幾篇知識文件中所介紹過的Canvas繪圖功能嗎?透過HTML5的Canvas繪圖功能,我們可以即時的產生圖形、並做出各種各種動態的圖形效果,而這些效果在以往都是需要透過第三方軟體協助才能夠作到。
  在這篇文章中,我們來試看看Canvas的另一個重要功能:影像處理,透過Canvas對於影像的支援能力,使得網頁的圖形處理不再需要依賴Server端來執行,我們在Client端利用javascript就能直接取用使用者的相片、Web Camera影像、網頁上的圖片等等,這不但減少了網路的傳輸與伺服器的負擔之外,網頁開發者也可以直接使用HTML加上javascript這樣的方式直接在用戶端就完成影像的處理,而不需要再另外依賴或學習撰寫伺服端的處理程式,最重要的一個好處是,我們不再需要利用第三方軟體,造成使用者在調用client端元件時會發生的種種繁雜認證與確認動作。

一)Canvas影像處理的基本步驟:

  在開始利用Canvas來處理影像之前,我們必須A) 先建立一個影像物件並開始B) 讀入影像的資料,當影像C) 讀入完畢後,便會觸發一個onload的事件,此時,我們便可在該事件的函式中,將讀入的影像資料繪製到Canvas物件中,開始進行相關的處理工作。
    這個基本步驟可寫成Javascript如下:





  接下來我們以凌陽創新網站上的圖片為例,使用Canvas提供的drawImage()方法針對該影像進行最基本的直接繪製、尺寸修改、影像截取等三種處理來作示範。

A)直接複製:














B)執行結果:

我們會發現網頁上有一張一模一樣的圖片(不是直接用連結的哦)。

C)尺寸修改:

要將圖片的尺寸縮小或放大,只要將ctx.drawImage(image, 0, 0); 這行再加入兩個參數,改為 ctx.drawImage(image, 0, 0, 寬度, 高度);就可以了,例如我們把圖片縮小為200x50如下:

D)截取部份影像:

    截取影像上的某個區域也是使用drawImage()這個方法,但是要額外給予影像的開始截取座標位置(sx, sy)以及截取的寬度(sw)和高度(sh),如下例:   
    ctx.drawImage(image, 0 ,0 ,350, 200, 0, 0, 350, 200);
我們截取了從(0,0)位置、寬長為350x200區塊的圖片(剛好為鍵盤的部份),並繪製在0,0的區域,繪製的圖形尺寸為350x200,執行結果如下:

二)Canvas像素處理:

  在Canvas所繪製的圖形或影像是作為一個整體的點陣圖(Bitmap)方式儲存的,我們我們可以造訪各個像素的資訊,換句話說,我們可以使用Javascript處理Canvas上的像素資訊,這是Canvas的一個很重要的特色。
  我們使用getImageData()以及putImageData()兩種方法針對drawImage()所繪製的影像來進行像素的處理,而這些像素資訊是用一維陣列的方式存放在CanvasPixelArray當中;在開始說明如何使用getImageData()及putImageData()方法之前,我們必須先瞭解實際像素和這些存放在CanvasPixelArray陣列中的像素資訊之間的關係。
  如左圖,影像上的每一個像素都會擁有四個數值,它們分別代表RGB三種顏色以及Alpha(透明度),這些數值的組合形成了最終每個像素的色彩及透明度;我們以下方圖形的橘色方框區塊為例,它的長寬分別是119px, 69px, 所以這個區塊總共有8211個像素,但是由於每個像素有四種數值,因此放到一維的CanvasPixelArray之後,總共會有32844個數值,所以,如果我們要找出某個像素的資訊,就要先確定該像素資訊是在陣列中的第幾筆到第幾筆。
    因此,當我們要得到一張圖片上(x,y)這個像素的影像資訊時,我們很容易就可找出這個公式:(注意,x,y都是從0,0開始)
Red =  (x + y * 影像寬度) * 4
Green =  (x + y * 影像寬度) * 4 + 1
Blue =  (x + y * 影像寬度) * 4 + 2
Alpha =  (x + y * 影像寬度) * 4 + 3
    知道影像的實際像素與存放資訊陣列之間的關係後,下面我們用一些實例來作一些練習。

A)變更R、G、B或Alpha值:

    請將下方程式碼放置於HTML的<body>標籤內,試著執行看看:














執行結果應該如下,您會看到圖形變充滿了藍色調:
這是因為我們把Red與Green兩個色彩的值變小,Blue的值奱大的結果,您可以試看看,隨意更改這些數值,看看會出現什麼結果!

B)將彩色圖片轉為黑白:

    如果我們將每一個像素的RGB三種數值皆設定為此其RGB值的平均,那麼,你會發現整張相片都變成黑白了,因為相同比重的三種RGB顏色混合後便會變成黑色,這是最快速的彩色轉黑白的方法,當然,要把黑白相片轉得更完美,應該還要考慮到加重光影的比例,但這部份與本文無關就先略過不談。
  我們修改上面範例中迴圈內的部份程式如下:





        執行結果,真的變成黑色的圖形了!

三)Canvas與外部設備的搭配:

看到這裏,你有沒有想到,既然Canvas可以抓取某個圖形來進行重繪及處理,那麼,web camera以及網頁上播放中的影片豈不是也可以如法炮製嗎?的確,透過HTML5的Canvas,我們可以對播放中的影片加入動態的效果或字幕,可以將web camera的即時畫面重繪到Canvas進行處理及判斷,作出類似人臉偵測、移動偵測等等功能,甚至於也可以進行現在流行的Gesture Recognition,換句話說,透過Canvas搭配HTML 5的影像支援,可以作出很多令人驚奇的新功能。

沒有留言:

張貼留言