canvas效能-drawImage渲染圖片
阿新 • • 發佈:2021-01-26
# canvas效能-繪製圖片
[TOC]
## canvas繪製圖片
一般我們繪製圖片會用到的方法是`drawImage`和`putImageData`,還有作為測試環境使用的`createPattern`
### drawImage
描述:
使用方式:
```javascript
ctx.drawImage(image,sx,sy,swidth,sheight,x,y,width,height)
```
- image的型別:
- HTMLImageElement:這些圖片是由Image()函式構造出來的,或者任何的img元素
- HTMLVideoElement:用一個HTML的video元素作為你的圖片源,可以從視訊中抓取當前幀作為一個影象
- HTMLCanvasElement:可以使用另一個canvas元素作為你的圖片源
- ImageBitmap:這是一個高效能的點陣圖,可以低延遲地繪製,它可以從上述的所有源以及其它幾種源中生成
- sx:可選。開始剪下的 x 座標位置
- sy:可選。開始剪下的 y 座標位置
- swidth:可選。被剪下影象的寬度
- sheight:可選。被剪下影象的高度
- x:在畫布上放置影象的 x 座標位置
- y:在畫布上放置影象的 y 座標位置
- width:可選。要使用的影象的寬度。(伸展或縮小影象)
- height:可選。要使用的影象的高度。(伸展或縮小影象)
### putImageData
描述: Canvas 2D API 將資料從已有的 [`ImageData`](https://developer.mozilla.org/zh-CN/docs/Web/API/ImageData) 物件繪製到點陣圖的方法。 如果提供了一個繪製過的矩形,則只繪製該矩形的畫素。此方法不受畫布轉換矩陣的影響。
使用方式:
```javascript
ctx.putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
```
- ImageData:包含畫素值的陣列物件
- dx:源影象資料在目標畫布中的位置偏移量(x 軸方向的偏移量)
- dy:源影象資料在目標畫布中的位置偏移量(y 軸方向的偏移量)
- dirtyX:可選 在源影象資料中,矩形區域左上角的位置。預設是整個影象資料的左上角(x 座標)
- dirtyY:可選 在源影象資料中,矩形區域左上角的位置。預設是整個影象資料的左上角(y 座標)
- dirtyWidth:可選 在源影象資料中,矩形區域的寬度。預設是影象資料的寬度
- dirtyHeight:可選 在源影象資料中,矩形區域的高度。預設是影象資料的高度。
### createPattern
描述:指定的方向內重複指定的元素,元素可以是圖片、視訊,或者其他 canvas 元素,被重複的元素可用於繪製/填充矩形、圓形或線條等等。
使用方式:
```javascript
ctx.fillStyle = ctx.createPattern(img,"repeat")
ctx.fill();
```
## 測試繪製耗時
> 測試圖片尺寸為(500x500)和(1920x1080)的jpg圖片
### drawImage
首先測試的是`drawImage`方法,通過繪製同一張圖片不同的資源型別下的耗時
#### Image型別
- 在空白canvas情況下渲染該圖片耗時:0.01ms左右
- 在使用了`createPattern`填充了canvas作為背景的情況下渲染該圖片耗時:0.01ms左右
#### ImageBitmap型別
- 在空白canvas情況下渲染該圖片耗時:1ms左右,(1920*1080)是1.8ms左右
- 在使用了`createPattern`填充了canvas作為背景的情況下渲染該圖片耗時:0.01ms左右,(1920*1080)是2ms左右
#### HTMLCanvasElement型別
- 在空白canvas情況下渲染該圖片耗時:0.01ms左右
- 在使用了`createPattern`填充了canvas作為背景的情況下渲染該圖片耗時:12ms左右,(1920*1080)是14ms左右
### putImageData
- 在空白canvas情況下渲染該圖片耗時:1ms左右
- 在使用了`createPattern`填充了canvas作為背景的情況下渲染該圖片耗時:2ms左右
| 渲染圖片方式 | 空白canvas下渲染耗時 圖片尺寸(500*500) | 使用createPattern鋪滿下渲染耗時 圖片尺寸(500*500) | 空白canvas下渲染耗時 圖片尺寸(1920*1080) | 使用createPattern鋪滿下渲染耗時 圖片尺寸(1920*1080) |
| :--------------------------- | ---------------------------------------- | --------------------------------------------------- | ------------------------------------------ | ----------------------------------------------------- |
| drawImage(Image) | 0.01ms | 0.01ms | 0.01ms | 0.01ms |
| drawImage(ImageBitmap) | 0.01ms | 0.01ms | 0.01ms | 0.01ms |
| drawImage(HTMLCanvasElement) | 0.01ms | 12ms | 0.01ms | 14ms |
| putImageData | 1ms | 2ms | 1.8ms | 3ms |
## 結論
> 1. 由上面的測試結果可以看出在空白canvas下渲染圖片,除了putImageData剩下的效能是一致的即Image = ImageBitmap = HTMLCanvasElement > putImageData。
> 2. 而使用了createPattern平鋪作為背景的情況下Image = ImageBitmap > putImageData > HTMLCanvasElement
> 3. 渲染圖片尺寸大小一般情況下對drawImage(Image)和drawImage(ImageBitmap)的影響較小,而且效能優越。
> 4. createPattern鋪滿的情況下drawImage(HTMLCanvasElement)的效能最差和drawImage(Image)能達到3個數量級的差距
> 5. drawImage(HTMLCanvasElement)在空白canvas下效能也很優越
> 6. putImageData的效能處於中等,使用createPattern鋪滿背景的情況下會有一定影響,不過不是太大
所以可以不使用使用createPattern鋪滿背景的情況下儘量不要使用,可以使用多層canvas,不必要的層級可以減少重繪。或者將平鋪的背景轉為Image物件使用。
當然以上的結論為我個人開發時的遇到的問題的總結,如果有誤請提出。因為樣本數量和圖片格式並沒有達到