Canvas drawImage() 失真

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)

JSBin Demo Link

非常感謝簡友微达夫寫了這麼一篇詳細的介紹, 真是受益良多。
文章描述把此現象的前因後果描述得相當清楚, 有興趣的朋友可以去了解了解。

推荐阅读更多精彩内容