Canvas是H5中新增的技術,主要運用在圖片的處理和動畫的繪製上,隨着Canvas的使用場景愈來愈多,瞭解Canvas對平時開發大有裨益,這篇文章將介紹Canvas基本圖片操做與處理html
將圖片上傳並繪製到Canva中是最多見的Canvas的圖片處理,這個上傳與繪製的過程是怎麼實現的呢?下面舉個例子:canvas
<canvas id="myCanvas"></canvas> <input type="file" id="file">
let upload = document.getElementById('file') upload.onchange = (event) => { let file = event.target.files[0] let fileReader = new FileReader() fileReader.onload = (e) => { let img = new Image() img.src = e.target.result img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0) } } fileReader.readAsDataURL(file) }
這個上傳與繪製的過程能夠總結爲兩步:api
這裏爲何要將base64格式的地址複製給Image對象,而後再將Image對象繪製到Canvas上而不是直接繪製呢?
這是由於Canvas上繪製時並不支持url做爲圖片源,Canvas只支持下面幾種圖片源:跨域
Canvas在繪圖時還有一個須要注意的點就是:Canvas在繪製不一樣域名下的圖片會出現跨域的錯誤,如圖:
被污染的Canvas,其實就是由於圖片跨域的問題的,這時須要兩步走:服務器
簡單示例代碼:cors
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0) console.log(canvas.toDataURL('image/png', 1.0)) }
更多跨域相關內容能夠看這裏ide
Canvas中圖片縮放的其實是經過畫布的縮放來達到的,所以默認的縮放中心是在畫布原點(0, 0),可是通常狀況下咱們作縮放時都但願圖片中心是縮放中心,這裏有兩種辦法能達到圖片中心做爲縮放中心的縮放效果,接下來分別來看這兩種辦法的示例:
第一種:wordpress
let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(0.5, 0.5) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height)
第一種方法就是畫布平移,先將畫布原點移到圖像中心,而後再作畫布縮放,再將畫布平移還原,最後繪製圖片,此時繪製的圖片就是以圖片中心作的縮放函數
第二種:性能
let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') let paintWidth = img.width / 2 let paintHight = img.height / 2 let originX = 0 // 原圖片X座標 let originY = 0 // 原圖片Y座標 let paintX = originX + (img.width - paintWidth) / 2 // 縮放後的圖片X座標 let paintY = originY + (img.height - paintHight) / 2 // 縮放後的圖片Y座標 context.drawImage(img, paintX, paintY, paintWidth, paintHight)
第二種就是最直接的計算當圖片以左上角做爲縮放中心,縮放後的圖片位置產生的位置偏移,將位置偏移加上在進行圖片繪製
Canvas的圖片旋轉和圖片縮放同樣,默認的旋轉中心也是畫布的原點(0, 0),此時也須要平移畫布來實現圖片的中心旋轉,舉個例子
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.rotate(30 * Math.PI / 180) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
鏡像變換能夠以圖片垂直中線爲對稱軸,左右鏡像的變換叫水平鏡像,或者水平中線爲對稱軸,上下鏡像的變換叫垂直鏡像,通常水平鏡像用的比較多,這裏就來看一個水平鏡像的例子:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(-1 , 1) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
原圖:
水平鏡像:
鏡像操做的原理其實很簡單:就是將scale設置爲負值,當x軸的縮放爲負值時,就是水平鏡像,當y軸的縮放爲負值時就是垂直鏡像
對稱軸翻轉指的是圖片沿着左上角至右下角的對角線翻轉,來看用代碼Canvas是怎麼實現的:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.translate(img.width / 2, img.height / 2) context.scale(-1 , 1) context.rotate(90 * Math.PI / 180) context.translate(-img.width / 2, -img.height / 2) context.drawImage(img, 0, 0, img.width, img.height) }
翻轉圖:
實現原理:先作水平鏡像,而後順時針旋轉90度,因爲先作的水平鏡像,座標軸會被水平翻轉,順時針旋轉90度實際是逆時針旋轉90度
圖片的灰度效果是Canvas很是常見的一個圖片處理效果,先來看實現灰度效果的代碼:
let img = new Image() img.setAttribute("crossOrigin",'Anonymous') img.src = './images/avatar.jpeg' img.onload = () => { let canvas = document.getElementById('myCanvas') canvas.width = img.width canvas.height = img.height let context = canvas.getContext('2d') context.drawImage(img, 0, 0, img.width, img.height) let imageData = context.getImageData(0, 0, img.width, img.height) let data = imageData.data for (let i = 0; i < data.length; i += 4) { let average = (data[i] + data[i + 1] + data[i + 2]) / 3 data[i] = average data[i + 1] = average data[i + 2] = average } context.putImageData(imageData, 0, 0) }
灰度效果圖:
實現思路:
這裏可能會有人對getImageData和putImageData這兩個api不是很熟悉,想要了解這個兩個api的能夠點getImageDataputImageData
Canva在圖片的處理上凸顯的做用愈來愈大,所以寫了這篇文章對Canvas基本圖片操做與處理作了簡單的介紹,但願看了這篇文章對你們瞭解Canvas能有所幫助。若是有錯誤或不嚴謹的地方,歡迎批評指正,若是喜歡,歡迎點贊