Canvas drawImage distortion
在使用Canvas實作拼接圖片的時候我們會使用drawImage方法
然而若是直接使用該方法將圖片導入canvas元素, 雖然能夠成功
但緊接而來的問題是圖片失真了, 這倒底是為什麼呢?
總而言之就是我們的圖片被裝置的devicePixelRatio屬性給影響了, 解決方法就是把canvas元素的樣式寬高設成我們實際想要的大寫, 接著把canvas畫布實際寬高設定為樣式大小乘上裝置devicePixelRatio的數值。
直接來看範例
// 取得圖一 cat
let cat = document.getElementById('cat')
// 取得圖二 dog
let dog = document.getElementById('dog')
// 手動建立 canvas, 並設定寬高
let canvas = document.createElement('canvas')
canvas.setAttribute('width', 150)
canvas.setAttribute('height', 150)
// 取得Canvas 2D物件
let ctx = canvas.getContext('2d')
// 取得裝置 devicePixelRatio
let devicePixelRatio = window.devicePixelRatio || 1
// 取得各瀏覽器 backingStoreRatio
let backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1
// 計算比例
let ratio = devicePixelRatio / backingStoreRatio
// 取得預設我們想要呈現的 canvas 大小
let canvasWidth = canvas.width
let canvasHeight = canvas.height
// 將"畫布寬高"依照比例放大
canvas.width = canvasWidth * ratio
canvas.height = canvasHeight * ratio
// 將"畫布樣式寬高", 設為我們想要呈現的寬高
canvas.style.width = `${canvasWidth}px`
canvas.style.height = `${canvasHeight}px`
// 將內容依照比例放大
ctx.scale(ratio, ratio);
// 畫上圖片
ctx.drawImage(cat, 0, 0, 60, 50)
ctx.drawImage(dog, 50, 50, 60, 50)
// 渲染至 body
document.body.appendChild(canvas)
非常感謝簡友微达夫寫了這麼一篇詳細的介紹, 真是受益良多。
文章描述把此現象的前因後果描述得相當清楚, 有興趣的朋友可以去了解了解。