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是直接调用event
- FileReader对象 可能有些旧的浏览器不支持
- 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的标识 连接地址http://code.ciaoca.com/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是画图的坐标起点 这里都设置为0 - canvas的
toDataURL
方法则可以将绘制出来的图像转化为Base64的值
toDataURL(fileType,opacity) 第一个参数代表文件类型,第二个参数代表转base64时压缩程度0~1 越小压缩越多
canvas的全部方法api参考http://www.w3school.com.cn/tags/html_ref_canvas.asp canvas用法非常丰富 不详细展开
旋转之后还需要调整画布和图像的宽和高(例如顺时针90度,画布的宽度和高度要交换)
这里在初始化宽高的时候,已经除以2了,意思是已经将图像的宽高都对半压缩
naturalHeight和naturalWeight指的是真实图片的宽高,是H5新增的属性,IE9以及以上 主流浏览器兼容
如果不支持的话还是使用width和height属性比较稳- 然后通过
上传
上传这里有两种方法
方法1:直接将压缩过的base64的图片信息上传(当前使用这个办法),base64就作为字符串直接在form表单中提交
方法2:将base64的文件再根据原始的file的名称和类型,重新转化成file,然后覆盖el-upload
的http-request
属性,这样就可以覆盖el-upload自带的上传文件方法,然后在提交按钮事件中加入this.$refs.uploadVisitor.submit();
代码
手动上传图片即可。
覆盖el-upload自带的上传方法,需要使用FormData对象,然后用$.ajax来提交,这里没有采用这个方法就不贴代码了
ElementUI h5 移动端照片拍照 本地预览 旋转压缩 并上传相关推荐
- H5拍照、预览、压缩、上传采坑记录
H5拍照.预览.压缩.上传采坑记录 公司项目前段时间需要实现手机拍照上传的功能,本来以为用createObjectURL和canvas可以很轻松的实现,结果发现问题多多,特此记录下来. DEMO预览( ...
- vue本地上传并预览php,vue.js 实现图片本地预览 裁剪 压缩 上传功能
以下代码涉及 Vue 2.0 及 ES6 语法. 目标 纯 javascrpit 实现,兼容ie9及以上浏览器,在本地做好文件格式.长宽.大小的检测,减少浏览器交互. 现实是残酷的,为了兼容Ie9 还 ...
- 移动端/手机端 完成图片旋转 压缩 剪裁 上传
本篇文章主要介绍移动端/手机端图片的旋转.压缩.剪裁.上传 这个功能的实现已经好了几次方案流程了,对最终的方案流程进行简述 实现功能的主要方法/思想 1.图片的选取主要是通过input实现 2.图片的 ...
- 带图片预览功能的图片上传
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决:
vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决: 参考文章: (1)vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决: (2)https://www.cnblogs.co ...
- ASP.NET工作笔记之一:图片上传预览及无刷新上传
转自:http://www.cnblogs.com/sibiyellow/archive/2012/04/27/jqueryformjs.html 最近项目里面涉及到无刷新上传图片的功能,其实也就是上 ...
- php 文件预览 水印,PHP图片上传,预览图上传,水印设置
//设置图片的存放目录 设置水印的存放地址如果愿意,可以给预览图.上传图片分设不同的存储地址 $img_path = $_SERVER['DOCUMENT_ROOT']."/data/img ...
- html 上传图片前预览,HTML实现图片上传前预览
HTML5 Upload #destination{ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(true,sizingMeth ...
- javascript 手机移动端 微信 拍照 录音 录视频并阿里oss上传
调用照相机,拍照 <input type="file" accept="image/*" capture="camera"> 1 ...
最新文章
- 中用BBP公式计算_【真课堂】7年级信息技术:数据计算
- Hybris (SAP旗下的软件公司)
- Bootstrap插件
- 前端学习(2653):对比vue2中的实现
- Android动画的实现 上
- chrome应用程序无法启动因为并行配置不正确_Win8打不开软件提示并行配置不正确的解决方法...
- java 合并csv_用java将三个csv表格文件,整合数据组合成一个文件。
- registered php streams sqlsrv,tp5与SQL Server的爱恨情仇(1)
- tomcat7不支持html5吗,HTTP状态404说明请求的资源()不可用。的Apache Tomcat/7.0.27
- 思科、华为、Dell visio图下载
- java自动化开发_五大Java自动化测试框架
- 《大数据技术原理与应用》(第三章 HDFS 课后答案)
- jovi五子棋下载_五子棋终结者
- go与python的前景_为什么说GO语言是未来前景看好的编程语言
- 65位高校教师接龙晒工资,全国各地高校,给打算入高校的博士们参考!
- 关于enq: US – contention
- 打开个税App:竟要补税两万多...
- 20220728使用电脑上的蓝牙和汇承科技的蓝牙模块HC-05配对蓝牙串口传输
- 如何改变思维导图的导图结构
- 职场面试中遇到的问题,八个方案,见招拆招