小程序壓縮圖片和普通 html 壓縮圖片思路一致。html
/** * 獲取圖片信息 * @param {string} imgObj 圖片對象path * @param {function} fn 回調函數 * @returns {ojbect} cbParams * { * height: 722, * width: 1366, * type: 'png', * path: '', * orientation: 'up', * errMsg: '' * } */ function getImageObject (src, fn) { uni.getImageInfo({ src: src, success (res) { fn(res) } }) } /** * 壓縮圖片 * @param {object} img 圖片 * @param {function} fn 回調函數 */ function compressImg (img, fn) { const selectorQuery = uni.createSelectorQuery() selectorQuery.select('#canvas') .fields({node: true, size: true}) .exec(res => { const canvas = res[0].node const ctx = canvas.getContext('2d') canvas.height = img.height canvas.width = img.width let seal = canvas.createImage(); seal.src = img.path; seal.onload = () => { ctx.drawImage(seal, 0, 0, img.width, img.height) const url = canvas.toDataURL('image/jpeg', .1) fn(url) } }) }
getImageObject(list[0].file.path, img => { compressImg(img, res => { console.log(res); }) })
新發現node
base64字符的長度就是文件尺寸 😛git
(ps::::這也太厲害了 👍👍👍👍👍👍👍👍)github
/** * 返回圖片尺寸 * @param {string} url base64 url * @param {functino} fn 返回圖片尺寸 */ function getSize(url, fn) { let arr = url.split(',')[1], bstr = atob(arr), n = bstr.length; fn(n) }
這裏假設壓縮上傳的文件。web
File
文件File
&& filereader.readAsDataURL(file) 生成 base64
編碼Image
對象 && Image.src = base64 url
canvas
&& ctx.drawImage()
&& canvas.toDataURL(type, encoderOptions)
base64 url
function Compress(obj) { this.file = obj.file this.fileType = this.file.type // mime type this.filename = this.file.name // 文件名 this.beforeSize = this.file.size this.factor = obj.factor // 壓縮比例(取值範圍:0-1) } /** * 生成 base64 url * @params { File } file 文件 * @params { function } fn 回調函數 * */ function toDataurl(file, fn) { const filereader = new FileReader() filereader.readAsDataURL(file) filereader.onload = () => { const url = filereader.result if (url) { // ---------vvvvvvvv 測試句 vvvvvvvv--------- addImg(url) // ---------^^^^^^^ 測試句 ^^^^^^^---------- fn(url) console.info('before: ' + file.size) } else { console.error('filereader error'); } } } /** * 建立 image 對象 * @params { string } base64 url * @params { string } filename 文件名 * @params { function } fn 回調函數 * */ function dataurl2File (url, filename, fn) { let type = url.split(',')[0].replace(/^.*:(.*);.*$/, '$1'), arr = url.split(',')[1], bstr = atob(arr), n = bstr.length; let u8arr = new Uint8Array(n); while(n --) { u8arr[n] = bstr.charCodeAt(n) } const file = new File([u8arr], filename, {type: type}) fn(file) } /** * 建立 image 對象 * @params { string } base64 編碼 * @params { function } fn 回調函數 * */ function createImg(dataurl, fn) { const img = new Image() img.src = dataurl img.onload = () => { fn(img) } } Compress.prototype = { /** * 文件生成 base64 url => 建立 image 對象 * */ init() { toDataurl(this.file, url => { createImg(url, img => { this.run(img) }) }) }, /** * 建立 canvas 對象 => 壓縮並轉化爲圖片 * */ run(img) { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = img.width canvas.height = img.height ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 此句爲實現壓縮關鍵句 this.newDataurl = canvas.toDataURL('image/jpeg', this.factor) // ---------vvvvvvvv 測試句 vvvvvvvv--------- addImg(this.newDataurl) // ---------^^^^^^^ 測試句 ^^^^^^^---------- dataurl2File(this.newDataurl, this.filename, (file) => { console.info('after: ' + file.size); if (this.beforeSize > file.size) { console.info('壓縮成功'); } else { console.error('壓縮失敗'); } }) } } /** * 對比壓縮先後的兩個圖片 * */ function addImg (url) { const img = new Image() img.src = url document.body.appendChild(img) }
/** * 獲取上傳文件,建立壓縮圖片實例,壓縮圖片 * */ function compressFile() { const dom = document.querySelector('[name=file]') dom.addEventListener('change', () => { const file = dom.files[0] const cp = new Compress({ file: file, factor: 0.1 }) cp.init() }) } window.onload = function () { compressFile() }
一、 小程序 canvas drawImage 報錯:canvas
TypeError: Failed to execute 'drawImage' 報錯
解決辦法小程序
let seal = canvas.createImage(); seal.src = img.path; seal.onload = () => { ctx.drawImage(seal, 0, 0, img.width, img.height) // 壓縮圖片 const url = canvas.toDataURL('image/jpeg', .1) }
⚠️:壓縮圖片時要注意 canvas.toDataURL
的第一個參數是 image/jpeg 或 image/webp 時能夠壓縮。😎app
在指定圖片格式爲 image/jpeg 或 image/webp 的狀況下,能夠從 0 到 1 的區間內選擇圖片的質量。若是超出取值範圍,將會使用默認值 0.92。其餘參數會被忽略。dom
瞭解JS壓縮圖片,這一篇就夠了
使用canvas壓縮圖片大小
HTMLCanvasElement.toDataURL()
Uint8Array
Blob
base64圖片編碼大小與原圖文件大小之間的聯繫函數
最後,測試代碼獻上
以上。
若有錯誤,請幫忙指出,謝謝各位大佬。(:」∠)_