首先我們看看base64 ,File 對象,Blob 對象長什么樣的,怎么來的
1. base64 : 可以直接當作鏈接地址使用
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGU....
2. File 對象:
File{ lastModified: 1649490762164 lastModifiedDate: Sat Apr 09 2022 15:52:42 GMT+0800 (GMT+08:00) {} name: "1649490762160-251.png" size: 25748 type: "image/png" webkitRelativePath: "" [[Prototype]]: File }
3. Blob 對象
Blob{ size: 25748 type: "image/png" [[Prototype]]: Blob }
除了base64 可以直接當作鏈接使用,File 對象和Bolb 對象也可以通過轉換 成base64 直接使用,或者使用
window.URL.createObjectURL(File 對象或者Bolb 對象) 直接生成鏈接 : 類似:blob:null/22ec44b8-5864-4960-8ea8-a71a7e40bb63
所以:能直接當作鏈接是使用在這三者關系中有
1. data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGU.... 2. blob:null/22ec44b8-5864-4960-8ea8-a71a7e40bb63
一:base64 轉 Blob 對象
//base64 轉 Blob對象 /* base64: data:image/png;base64,iVB.... /* Blob:{...} */ function base64ToBlob(data) { var arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }
二: base64 轉 File 對象
/** base64 轉 File 對象 /* @param data base64 /* @param filename 自定義文件名 /* @return File 對象 */ function base64ToFile(data, filename) { var arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); let suffixArr = mime.split("/") if (suffixArr.length && !filename) { let suffix = suffixArr[suffixArr.length - 1] filename = new Date().getTime() + "-" + Math.floor((Math.random() * 10000)) + "." + suffix } while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new File([u8arr], filename, { type: mime }); }
三: File 對象,Blob 對象 轉base64
//blob ,File 對象 轉 base64 function blobFileTobase64(blobFile) { let reader = new FileReader() reader.readAsDataURL(blobFile); return new Promise((resolve, reject) => { reader.onload = function () { resolve(this.result) } reader.onerror = (err) => { reject(err); }; }) }
四: blob鏈接轉 base64 :利用canvas.toDataURL的API轉化成base64
blob:null/22ec44b8-5864-4960-8ea8-a71a7e40bb63 轉為 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABGU....
function urlToBase64(url, type = "image/png") { return new Promise((resolve, reject) => { let img = new Image() img.src = url img.onload = function () { let canvas = document.createElement("canvas") canvas.width = this.naturalWidth canvas.height = this.naturalHeight let ctx = canvas.getContext("2d") ctx.drawImage(img, 0, 0) let result = canvas.toDataURL(type || 'image/png') resolve(result) } img.onerror = function (err) { reject(err) } }) }
五: 壓縮圖片:接收一個File/Blob 對象,返回的是一個base64
/* blobFile:file/blob 對象 option:{type:"image/jpeg",width:'',height:"",quality:0.92,scale:1} */ function compressImg(blobFile, option = {}) { return new Promise((resolve, reject) => { let reader = new FileReader() reader.onload = function () { let img = new Image() img.src = this.result img.onload = function () { console.log("原圖片大小:", this.src.length);//這是base64 ,所以可以指定圖片大小 let imgSize = this.src.length; let targetSize = 100 * 1024; if (imgSize <= targetSize) { return resolve(this.src) } let canvas = document.createElement("canvas") let ctx = canvas.getContext("2d") //原圖尺寸 let imgW = this.naturalWidth let imgH = this.naturalHeight //新圖比例大小 let scale = option.scale || 1; let ratio = imgW / imgH; //寬高比例 let targetW = option.width || imgW * scale let targetH = option.height || imgH * scale canvas.width = targetW canvas.height = targetH ctx.drawImage(img, 0, 0, targetW, targetH) let fileType = blobFile.type || option.type || 'image/jpeg' let quality = option.quality || 0.5 let result = canvas.toDataURL(fileType, quality) console.log("壓縮后:", result.length) resolve(result) } } reader.onerror = function () { reject(new Error(`${blobFile} must is Blob or File 對象`)) } reader.readAsDataURL(blobFile) }) }
六: Blob對象 與File 對象 相互轉換
利用base64 作中間 : blob=>base64=>File / File=>base64=>blob