vue項(xiàng)目拍照或上傳圖片并實(shí)現(xiàn)轉(zhuǎn)化為base64格式
vue項(xiàng)目拍照或上傳圖片并轉(zhuǎn)化為base64格式
需求
vue項(xiàng)目中,H5點(diǎn)擊按鈕觸發(fā)上傳圖片或拍照上傳,上傳的圖片使用base64位傳輸?shù)胶笈_(tái),最終實(shí)現(xiàn)身份證拍照識(shí)別功能。
實(shí)現(xiàn)過(guò)程
(1)設(shè)置一個(gè)按鈕和一個(gè)隱藏的input,點(diǎn)擊按鈕是觸發(fā)按鈕上傳圖片和拍照功能
<div> <input id="filePhoto" type="file" ref="file" accept="image/*" hidden @change="onInputChange($event)" /> <div @click="triggerUpload"> <img src="@res/images/scenicSpots/add-circle-white.png" /> <span>上傳圖片</span> </div> </div>
(2)將上傳的圖片轉(zhuǎn)化為base64格式
//點(diǎn)擊圖片觸發(fā)文件上傳 triggerUpload() { $("#filePhoto").click(); }, //文件上傳到瀏覽器觸發(fā)事件 onInputChange(el) { var self = this; var file = el.target.files[0]; console.log(file) var type = file.type.split('/')[0]; if(type === 'image') { //將圖片轉(zhuǎn)化為base64 var reader = new FileReader(); reader.readAsDataURL(file); // readAsDataURL方法可以將上傳的圖片格式轉(zhuǎn)為base64,然后在存入到圖片路徑, reader.onload = function () { var image = reader.result; // image即base64格式,后面調(diào)用后端請(qǐng)求傳入image } }else{ self.$toast.showToast('請(qǐng)正確上傳圖片'); } },
vue圖片上傳組件,包括base64、二進(jìn)制上傳及圖片旋轉(zhuǎn)
最近做的vue項(xiàng)目中好多涉及到圖片上傳的,為了方便開發(fā)就進(jìn)行了相關(guān)總結(jié)。
因?yàn)楣居泻枚囗?xiàng)目,并且使用的是不同后臺(tái)語(yǔ)言,有的需要通過(guò)base64字符串傳遞,有的需要轉(zhuǎn)換成二進(jìn)制數(shù)據(jù)流傳遞,有的可以直接使用from表單進(jìn)行提交。后來(lái)有涉及到ios上拍照?qǐng)D片會(huì)旋轉(zhuǎn)的問(wèn)題,也一并進(jìn)行了封裝。
好了廢話不多說(shuō)直接上代碼。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>圖片上傳</title> </head> <body> <form id="upImg"> <input type='file' accept="image/*" name="avatar" placeholder="" id="img" /> </form> <img src="" alt="" id='preImg'> <!-- 需要引入exif.js插件 --> <script src='./exif.js'></script> <script> var domImg = document.querySelector('#img') //添加DOM事件 domImg.onchange = function upLoadImg(e, type) { let files = e.target.files || e.dataTransfer.files; if (!files.length) return; if (files[0].type.indexOf("image") < 0) { alert("上傳了非圖片"); return; } if (files[0].size > 5 * 1000000) { alert("上傳文件過(guò)大"); return; } // 圖片壓縮成base64 compress(e.target, (base64, imgFile) => { var upImage = new FormData(); upImage.append("fileName", imgFile.name); var blob = convertImgDataToBlob(base64); upImage.append("file", blob); //上傳圖片接口 this.$http({ method: "POST", url: interfaced.aliYun, body: upImage }).then( res => { console.log(res); }, err => { console.log(err); } ); }); //將base64轉(zhuǎn)換成二進(jìn)制函數(shù) function convertImgDataToBlob(base64Data) { var format = "image/jpeg"; var base64 = base64Data; var code = window.atob(base64.split(",")[1]); var aBuffer = new window.ArrayBuffer(code.length); var uBuffer = new window.Uint8Array(aBuffer); for (var i = 0; i < code.length; i++) { uBuffer[i] = code.charCodeAt(i) & 0xff; } var blob = null; try { blob = new Blob([uBuffer], { type: format }); } catch (e) { window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; if (e.name == "TypeError" && window.BlobBuilder) { var bb = new window.BlobBuilder(); bb.append(uBuffer.buffer); blob = bb.getBlob("image/jpeg"); } else if (e.name == "InvalidStateError") { blob = new Blob([aBuffer], { type: format }); } else {} } return blob; } //將圖片壓縮成base64函數(shù) function compress(event, callback) { //圖片方向角 var Orientation = null; var file = event.files[0]; var reader = new FileReader(); //獲取照片方向角屬性,用戶旋轉(zhuǎn)控制 EXIF.getData(file, function() { EXIF.getAllTags(this); Orientation = EXIF.getTag(this, 'Orientation'); }); reader.onload = function (e) { var image =document.createElement("img"); image.onload = function () { //使用canvas重繪圖片 var canvas = document.createElement("canvas"); var x = this.width; var y = this.height; this.width = 375 * 2; this.height = this.width / x * y; var width = this.width; var height = this.height; canvas.width = this.width; canvas.height = this.height; var context = canvas.getContext("2d"); context.clearRect(0, 0, width, height); //對(duì)圖片進(jìn)行旋轉(zhuǎn) switch (Orientation) { case 3: context.rotate(180 * Math.PI / 180); context.drawImage(this, -this.width, -this.height, this.width, this.height); break; case 6: context.rotate(90 * Math.PI / 180); context.drawImage(this, 0, -this.width, this.height, this.width); break; case 8: context.rotate(270 * Math.PI / 180); context.drawImage(this, -this.height, 0, this.height, this.width); break; case 2: context.translate(this.width, 0); context.scale(-1, 1); context.drawImage(this, 0, 0, this.width, this.height); break; case 4: context.translate(this.width, 0); context.scale(-1, 1); context.rotate(180 * Math.PI / 180); context.drawImage(this, -this.width, -this.height, this.width, this.height); break; case 5: context.translate(this.width, 0); context.scale(-1, 1); context.rotate(90 * Math.PI / 180); context.drawImage(this, 0, -this.width, this.height, this.width); break; case 7: context.translate(this.width, 0); context.scale(-1, 1); context.rotate(270 * Math.PI / 180); context.drawImage(this, -this.height, 0, this.height, this.width); break; default: context.drawImage(this, 0, 0, this.width,this.height); } var quality = 0.9; //壓縮程度 var data; var result; var length; //控制圖片上傳的大小,注意若圖片過(guò)大 ajax上傳的時(shí)候會(huì)出現(xiàn)參數(shù)為null的錯(cuò)誤 //這里如果圖片過(guò)大會(huì)將圖片壓縮程度放大 do { data = canvas.toDataURL("image/jpeg", quality); length = data.length; result = (length / 4 * 3 + 1023) / 1024; //計(jì)算壓縮后圖片的大小 quality -= 0.05; } while (result > 450); //data:base64 document.querySelector('#preImg').src = data callback(data, event.files[0]); }; image.src = e.target.result; }; reader.readAsDataURL(file); } } </script> </body> </html>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
axios+vue請(qǐng)求時(shí)攜帶cookie的方法實(shí)例
做項(xiàng)目時(shí)遇到一個(gè)需求,后端需要在接口請(qǐng)求時(shí),對(duì)用戶登陸狀態(tài)進(jìn)行判斷,需要在請(qǐng)求時(shí)攜帶Cookie,下面這篇文章主要給大家介紹了關(guān)于axios+vue請(qǐng)求時(shí)攜帶cookie的相關(guān)資料,需要的朋友可以參考下2022-09-09vue返回上一頁(yè)(后退)的幾種方法與區(qū)別說(shuō)明
這篇文章主要介紹了vue返回上一頁(yè)(后退)的幾種方法與區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue v-html指令詳細(xì)解析與代碼實(shí)例(最新推薦)
v-html是Vue.js框架中的一個(gè)指令,用于將數(shù)據(jù)中的HTML代碼動(dòng)態(tài)渲染到頁(yè)面上,它主要用于渲染一些靜態(tài)的HTML內(nèi)容或者從后臺(tái)獲取的富文本數(shù)據(jù),下面介紹Vue v-html詳細(xì)解析與代碼實(shí)例,感興趣的朋友一起看看吧2024-12-12利用Vue+intro.js實(shí)現(xiàn)頁(yè)面新手引導(dǎo)流程功能
在同學(xué)們使用某些網(wǎng)站的新版本頁(yè)面的時(shí)候,經(jīng)常會(huì)出現(xiàn)一個(gè)類似于新手引導(dǎo)一樣的效果,來(lái)幫助同學(xué)們更好的熟悉新版本頁(yè)面的功能和使用,這篇文章主要給大家介紹了關(guān)于如何利用Vue+intro.js實(shí)現(xiàn)頁(yè)面新手引導(dǎo)流程功能的相關(guān)資料,需要的朋友可以參考下2023-11-11Vue 路由切換時(shí)頁(yè)面內(nèi)容沒(méi)有重新加載的解決方法
今天小編就為大家分享一篇Vue 路由切換時(shí)頁(yè)面內(nèi)容沒(méi)有重新加載的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue清空數(shù)組的幾個(gè)方式(小結(jié))
本文主要介紹了vue清空數(shù)組的幾個(gè)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12