100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > ElementUI h5 移动端照片拍照 本地预览 旋转压缩 并上传

ElementUI h5 移动端照片拍照 本地预览 旋转压缩 并上传

时间:2021-04-22 11:57:55

相关推荐

ElementUI h5 移动端照片拍照 本地预览 旋转压缩 并上传

文章目录

调用摄像头拍照本地预览旋转压缩上传

功能需求是移动端扫描二维码之后,跳转到在线网页进行自拍,然后上传拍照结果。

调用摄像头拍照

在h5中,使用input type="file"的 capture="camera"这个属性就可以调用摄像头

在这里我们使用的是ElementUI的组件,实际这个组件里面是包含一个input type="file"的元素的

所以我们只需要修改这个元素的capture和accept属性就可以了

但是vue本身是不推荐修改dom元素的,所以可以引入jQuery方便操作

在package.json中引入jquery

"jquery":"^3.4.1",

在main.js中引用jquery

import $ from 'jquery'

在调用摄像头的vue文件中, 以下是部分代码

html部分的代码如下

<el-uploadclass="mobile-avatar-uploader"ref="uploadVisitor":action="upLoadUrl":auto-upload="false":on-change="photoPreview":show-file-list="false"><img v-if="editForm.visitorPhoto" :src="editForm.visitorPhoto" class="mobile-avatar"><i v-else class="el-icon-camera mobile-avatar-uploader-icon"></i></el-upload>

在加载页面的时候使用jquery的代码来获取input file的dom节点并加上accept和camera属性

mounted代码如下:

let obj = $("#avatarDiv input");obj.attr('accept', 'image/*');obj.attr('capture', 'camera');

ref属性用来手动操作文件调用默认上传方法,可以不设置(如果调用默认上传方法需要设置)

action属性用来设置文件默认上传地址,一般不为空,没用的话随意填写

本地预览

ElementUI的el-upload组件,在官网上有用户头像上传的实例,同时也提供了auto-upload属性

如果把auto-upload属性改为false,那么选中照片之后不会自动上传到服务器,但是同时也无法预览

所以只好给on-change加上一个方法,在选中文件之后,手动将文件显示出来

组件代码见第一部分

下面是on-change绑定的预览方法

photoPreview(file, fileList) {if (file.status == 'ready') {var _this = this;var event = event || window.event;var file = event.target.files[0];Exif.getData(file, function () {_this.orientation = Exif.getTag(this, 'Orientation');});var reader = new FileReader();_this.fileType = file.type;//转base64reader.onload = function (e) {_this.photoCompress(e.target.result, function (base64Codes) {_this.editForm.visitorPhoto = base64Codes; //将图片路径赋值给src});};reader.readAsDataURL(file);}},

通过file.status=='ready’判断是选择照片/拍照,而不是上传,因为不管是拍照还是上传都会触发on-change事件通过event.target.files[0]获取拍照文件event||window.event主要是为了浏览器兼容,IE是window.event firefox是直接调用eventFileReader对象 可能有些旧的浏览器不支持Exif之后再讲

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。

FileReader实例拥有4个方法,3个用来读取文件,一个用来中断读取

abort 参数none 中断读取readAsBinaryString 参数file 将文件读取为二进制码readAsDataUrl参数file 将文件读取为data:开头的字符串,实质就是Data URL 是将小文件(图像等)直接嵌入文档的方案,base64的方式由此来获得readAsText file,[encoding] 文本方式读取文件,读取结果是文本的内容

读取结果会存储在FileReader的result属性中

处理事件简介:

onabort 中断时触发onerror 出错时触发onload读取成功时触发onloadend 读取完成时触发 无论成功失败onloadstart 读取开始时触发onprogress 读取中

文件开始读取后无论成功失败都会填充result属性,读取失败result属性会赋值null,否则会填充读取结果

onload读取成功之后,直接将base64位赋值给img元素的src属性,就可以预览图片了!

旋转压缩

利用canvas将base64的文件压缩

手机前端摄像头拍照经常会拍出来的照片是横着的,这里引用exif来调整照片的方向现在手机拍照的像素都很高,所以拍照之后图片文件都过大,所以需要压缩

/*** 图片压缩(利用canvas)* @param path图片路径* @param obj压缩配置width,height,quality,不传则按比例压缩* @param callback 回调函数*/photoCompress(path, callback) {var _this = this;//解决照片旋转问题let img = new Image();img.src = path;img.onload = function () {var that = this;//生成canvasvar canvas = document.createElement('canvas'),ctx = canvas.getContext('2d');// 默认按比例压缩var degree = 0, drawWidth, drawHeight, width, height;//drawWidth = that.naturalWidth;//drawHeight = that.naturalHeight;drawWidth = that.width / 2;drawHeight = that.height / 2;canvas.width = width = drawWidth;canvas.height = height = drawHeight;//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式if (_this.orientation != "" && _this.orientation != 1) {switch (_this.orientation) {//iphone横屏拍摄,此时home键在左侧case 3:degree = 180;drawWidth = -width;drawHeight = -height;break;//iphone竖屏拍摄,此时home键在下方(正常拿手机的方向)case 6:canvas.width = height;canvas.height = width;degree = 90;drawWidth = width;drawHeight = -height;break;//iphone竖屏拍摄,此时home键在上方case 8:canvas.width = height;canvas.height = width;degree = 270;drawWidth = -width;drawHeight = height; break;}}//使用canvas旋转校正ctx.rotate(degree * Math.PI / 180);ctx.drawImage(that, 0, 0, drawWidth, drawHeight);// 默认图片质量为0.4// 回调函数返回base64的值var base64 = canvas.toDataURL(_this.fileType, 0.4);callback(base64);}},

image的加载事件(onload),是在一张图片被完整加载后触发的事件,一般用这个方法加载图片后获取图片的宽和高

ios可能会遇到onload不执行的情况 可以利用img的complete属性或者在onload里面加上setTimeout延时来处理

complete是无论img的src是否有值,只要加载完image对象和属性, complete属性就会变成true,而onload事件需要图片有src并加载完成后,才会触发

在拍摄图片之后,就用Exif获取图像的原始数据,例如:拍照方向,拍摄事件,ISO感光度,GPS地理位置等数据

然后使用canvas根据拍照方向在进行调整和压缩

exif主要用来处理拍摄的照片,兼容主流浏览器,不支持IE10以下浏览器

首先在package里面引入exif"exif-js":"^2.3.0",

exif提供的 API方法主要有

Exif.getData(img,callback) 获取图像数据Exif.getTag(img,tag) 获取图像的某个数据Exif.getAllTags(img) 获取图像的全部数据Exif.pretty(img) 获取图像的全部数据,值以字符串的形式范围

这里先用到getData这个方法来获取图像的数据

然后在回调中用到了getTag这个方法,tag参数传的是’Orientation’,来获取拍摄方向

orientation不同的值代表不同的方向,具体可以看代码中的注释

tag还有很多种参数 详情参考Exif的标识 连接地址/javascript/exif-js/

将获取的拍摄方向存储在vue的数据中,然后在压缩图片的时候,根据拍摄方向来调整图片的方向

这里使用了h5的canvas画布来绘制图像,完成压缩和调整方向的功能

canvas简介

canvas是一个容器(画布),他的getContext()方法用来获取一个对象,这个对象提供了再画布上绘图的方法和属性。

canvas兼容ie9以及更高、chrome和safari等主流浏览器

创建canvas的方法一般如下

var canvas = document.createElement(‘canvas’) , ctx = canvas.getContext(‘2d’);

然后通过rotate方法来旋转图片

ctx.rotate(20*Math.PI/180); 代表顺时针旋转20度canvas绘制图片旋转是按照左上角顶点来旋转的 所以drawImage的宽高才需要负数

例如旋转90度之后,如果不调整其他参数,就看不到绘制图片了(因为应旋转到左边去了)

所以要先把drawImage的height参数改成负数,让图片相对上移(绝对来说是往右移)

然后修改画布的宽高(对换),这样就能把图片从横的画成竖着的(可以在w3school在线测试rotate方法就懂了)通过drawImage方法来绘制图片

context.drawImage(img,x,y,width,height); 在画布上定位图像,并规定图像的宽度和高度:

x y是画图的坐标起点 这里都设置为0canvas的toDataURL方法则可以将绘制出来的图像转化为Base64的值

toDataURL(fileType,opacity) 第一个参数代表文件类型,第二个参数代表转base64时压缩程度0~1 越小压缩越多

canvas的全部方法api参考/tags/html_ref_canvas.asp canvas用法非常丰富 不详细展开

旋转之后还需要调整画布和图像的宽和高(例如顺时针90度,画布的宽度和高度要交换)

这里在初始化宽高的时候,已经除以2了,意思是已经将图像的宽高都对半压缩

naturalHeight和naturalWeight指的是真实图片的宽高,是H5新增的属性,IE9以及以上 主流浏览器兼容

如果不支持的话还是使用width和height属性比较稳

上传

上传这里有两种方法

方法1:直接将压缩过的base64的图片信息上传(当前使用这个办法),base64就作为字符串直接在form表单中提交

方法2:将base64的文件再根据原始的file的名称和类型,重新转化成file,然后覆盖el-uploadhttp-request属性,这样就可以覆盖el-upload自带的上传文件方法,然后在提交按钮事件中加入this.$refs.uploadVisitor.submit();代码

手动上传图片即可。

覆盖el-upload自带的上传方法,需要使用FormData对象,然后用$.ajax来提交,这里没有采用这个方法就不贴代码了

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。