技術貼-前端canvas圖片壓縮

canvas and svg

canvas是一個可以使用js指令碼來繪製圖形的HTML元素,它是chrome為我們提供好的一個繪製2D圖形的api。

svg是使用XML標籤來繪製2D圖形的語言,和canvas最大的寫法上的區別就是:

(1)。svg的寫法和編寫html標籤一樣,而canvas則需要使用js;

(2)。canvas 是在規定的畫布上面逐畫素進行渲染的,當我們在瀏覽器開發者工具對其進行選中時,是不能選中的;

(3)。canvas是依賴解析度是點陣圖,svg不依賴解析度是可縮放向量圖形;

(4)。canvas比較適用在動畫、遊戲或者需要大量密集影象中,svg因為是渲染在dom中,所以不適合大量使用,不適合遊戲應用,一般比較適合做一些icon適用。

編寫區別

canvas

編寫canvas標籤

獲取cancvas dom物件

const canvas = document。getElementById(‘canvas’)

獲取cancvas 物件

const ctx = canvas。getContext(‘2d’)

設定繪圖屬性,呼叫繪圖api

//繪製矩形 ctx。fillStyle = ‘red’ ctx。fillRect(0,0,50,50)//繪製線段 ctx。beginPath() ctx。lineWidth = 3 ctx。strokeStyle = ‘blue’ ctx。moveTo(500, 100) ctx。lineTo(600, 200) ctx。lineTo(800, 100) ctx。lineTo(500, 100) ctx。stroke() //繪製圓形 ctx。beginPath() ctx。lineWidth = 2 ctx。strokeStyle = ‘green’ ctx。fillStyle = ‘red’ ctx。arc(200,200,50,0,2*Math。PI) ctx。stroke() ctx。fill()//繪製點 ctx。beginPath() ctx。lineWidth = 1 ctx。strokeStyle = ‘blue’ ctx。moveTo(400, 400) ctx。lineTo(401, 401) ctx。stroke()

技術貼-前端canvas圖片壓縮

1

svg

和書編寫html標籤一樣

編寫一個svg 容器

繪製矩形

繪製圓,其中設定圖形的樣式,可以是屬性的方式,也可以現在style裡面

技術貼-前端canvas圖片壓縮

2

canvas實際使用場景

圖片壓縮

前端圖片壓縮,已經有現成的api可以呼叫,主要還是透過canvas的drawImage api 把圖片繪製在規定大小的畫布上。

上傳圖片時,透過呼叫new FileReader(),獲取圖片的base64資源

upload。addEventListener(‘change’, function(e) { const [ file ] = e。target。files if (!file) return const {type:fileType, size: fileSize} = file if ( ACCEPT。indexOf(fileType) < 0 ) { upload。value = ‘’ return alert(‘型別不支援’) } if ( fileSize > MAXSIZE ) { upload。value = ‘’ alert(`檔案大小超出${MAXSIZE_STR}`) return } //圖片壓縮 //1。將圖片轉為base64 converImageToBase64(file, compress) })

function converImageToBase64(file, callback) { let reader = new FileReader() reader。addEventListener(‘load’, function(e) { const base64Img = e。target。result callback && callback(base64Img) reader = null }) reader。readAsDataURL(file) }

圖片壓縮核心 drawImage

function compress(base64Img, callback) { let maxW = 400 // 最大寬 let maxH = 400 // 最大高 const image = new Image() image。addEventListener(‘load’, function(e) { let ratio; //圖片壓縮比 let needCompress = false //是否需要壓縮 if (maxW < image。naturalWidth) { //如果上傳圖片的寬大於限制的寬度,那麼需要壓縮,用圖片的寬度 / 最大的寬度 此時 maxW = 400,maxH也等比例縮放ratio needCompress = true ratio = image。naturalWidth / maxW maxH = image。naturalHeight / ratio } if (maxH < image。naturalHeight) { //圖片高度比maxH大 needCompress = true ratio = image。naturalHeight / maxH maxW = image。naturalWidth / ratio } if (!needCompress) { //如果不需要壓縮,也就是上傳的圖片寬高在限制的範圍內,就用圖片的原始寬高 maxW = image。naturalWidth maxH = image。naturalHeight } const canvas = document。createElement(‘canvas’) canvas。setAttribute(“id”, “canvas”) canvas。width = maxW canvas。height = maxH canvas。style。display = ‘none’ document。body。appendChild(canvas) const ctx = canvas。getContext(‘2d’) ctx。clearRect(0,0,maxW, maxH) ctx。drawImage(image, 0, 0, maxW, maxH) const compressImage = canvas。toDataURL(‘image/jpeg’, 0。8) callback && callback(compressImage) canvas。remove() }) image。src = base64Img document。body。appendChild(image) }