vue项目拍照或上传图片并实现转化为base64格式
作者:钥零零
这篇文章主要介绍了vue项目拍照或上传图片并实现转化为base64格式方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
vue项目拍照或上传图片并转化为base64格式
需求
vue项目中,H5点击按钮触发上传图片或拍照上传,上传的图片使用base64位传输到后台,最终实现身份证拍照识别功能。
实现过程
(1)设置一个按钮和一个隐藏的input,点击按钮是触发按钮上传图片和拍照功能
<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)将上传的图片转化为base64格式
//点击图片触发文件上传 triggerUpload() { $("#filePhoto").click(); }, //文件上传到浏览器触发事件 onInputChange(el) { var self = this; var file = el.target.files[0]; console.log(file) var type = file.type.split('/')[0]; if(type === 'image') { //将图片转化为base64 var reader = new FileReader(); reader.readAsDataURL(file); // readAsDataURL方法可以将上传的图片格式转为base64,然后在存入到图片路径, reader.onload = function () { var image = reader.result; // image即base64格式,后面调用后端请求传入image } }else{ self.$toast.showToast('请正确上传图片'); } },
vue图片上传组件,包括base64、二进制上传及图片旋转
最近做的vue项目中好多涉及到图片上传的,为了方便开发就进行了相关总结。
因为公司有好多项目,并且使用的是不同后台语言,有的需要通过base64字符串传递,有的需要转换成二进制数据流传递,有的可以直接使用from表单进行提交。后来有涉及到ios上拍照图片会旋转的问题,也一并进行了封装。
好了废话不多说直接上代码。
<!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("上传文件过大"); 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转换成二进制函数 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函数 function compress(event, callback) { //图片方向角 var Orientation = null; var file = event.files[0]; var reader = new FileReader(); //获取照片方向角属性,用户旋转控制 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); //对图片进行旋转 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; //控制图片上传的大小,注意若图片过大 ajax上传的时候会出现参数为null的错误 //这里如果图片过大会将图片压缩程度放大 do { data = canvas.toDataURL("image/jpeg", quality); length = data.length; result = (length / 4 * 3 + 1023) / 1024; //计算压缩后图片的大小 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>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。