2017-08-15 40 views
1

我想壓縮用戶在正面上傳的圖像。爲什麼畫布放大圖像大小?

源圖像是651Kb(Mac OS),並且在將尺寸格式(1920 * 1080)更改爲(1000 * 562)後,圖片大小變爲1.2Mb(瀏覽器),1.4Mb(Mac OS),1.29 Mb(Windows 7)。無論如何,這是增加原始圖像的大小。

爲什麼?

源圖像:http://7xoaqt.com1.z0.glb.clouddn.com/maikailun.jpg

代碼:https://codepen.io/maicss/pen/ayLgdo/

<input type="file" multiple accept="image/*"> 

<canvas></canvas> 


const $ = document.querySelector.bind(document) 
const input = $('input') 
const canvas = $('canvas') 
const ctx = canvas.getContext('2d') 

const readableSize = (size) => { 
    return size/1024 > 1024 ? (~~(10 * size/1024/1024))/10 + 'MB' : ~~(size/1024) + 'KB' 
} 

input.onchange = function (e) { 
    const files = e.target.files; 
    [].forEach.call(files, file => { 
    const img = new Image() 
    img.src = URL.createObjectURL(file) 
    img.onload = function() { 
     let radio = 1 
     if (Math.min(this.height, this.width) > 1000) { 
      radio = Math.max(this.height/1000, this.width/1000) 
     } 
     canvas.height = this.height/radio 
     canvas.width = this.width/radio 

     ctx.fillRect(0, 0, canvas.width, canvas.height); 
     ctx.drawImage(img, 0, 0, canvas.width, canvas.height) 
     canvas.toBlob(function (b) { 
      console.log(readableSize(b.size)) 
     }) 
     URL.revokeObjectURL(this.src) 
    } 
    }) 
} 

回答

1

對於圖像類型的方法toBlob() with no mime-type argument將默認產生一個PNG文件,該文件是一個無損格式,因此通常比類型的源極圖像大JPEG。

改變這一行:

canvas.toBlob(function (b) { 
    console.log(readableSize(b.size)) 
}) 

採取圖像MIME參數使得它使用JPEG以及一個質量設置:

canvas.toBlob(function(b) { 
    console.log(readableSize(b.size)) 
}, "image/jpeg", 0.7); 

實驗的質量參數([0.0,1.0] )以滿足您的需求。

+0

是的,你是對的。但我想知道「異常」數據來自哪裏以及哪裏。 – maicss

+0

它來源於PNG使用不同於JPEG的壓縮方案,它也原樣保留所有數據,從而產生更大的尺寸。畫布不會跟蹤源圖像和類型,只有在畫布上存在的內容與原始圖像和輸出圖像之間沒有關聯,除了通過畫布產生的內容之外。要解決問題,請參閱答案(將JPEG用作具有質量參數的源圖像)。 – K3N

+0

或換句話說:新圖像是從畫布位圖生成的,而不是原始圖像。由於默認值是PNG,因此圖像會更大(通常是反正)。匹配原始圖像使用相同的壓縮方案,即。 jpeg代替png, – K3N