文章目录

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

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

调用摄像头拍照

在h5中,使用input type="file"的 capture="camera"这个属性就可以调用摄像头
在这里我们使用的是ElementUI的组件,实际这个组件里面是包含一个input type="file"的元素的
所以我们只需要修改这个元素的capture和accept属性就可以了
但是vue本身是不推荐修改dom元素的,所以可以引入jQuery方便操作

  1. 在package.json中引入jquery
 "jquery":"^3.4.1",
  1. 在main.js中引用jquery
import $ from 'jquery'
  1. 在调用摄像头的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);}},
  1. 通过file.status=='ready’判断是选择照片/拍照,而不是上传,因为不管是拍照还是上传都会触发on-change事件
  2. 通过event.target.files[0]获取拍照文件
  3. event||window.event主要是为了浏览器兼容,IE是window.event firefox是直接调用event
  4. FileReader对象 可能有些旧的浏览器不支持
  5. 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的文件压缩

  1. 手机前端摄像头拍照经常会拍出来的照片是横着的,这里引用exif来调整照片的方向
  2. 现在手机拍照的像素都很高,所以拍照之后图片文件都过大,所以需要压缩
/*** 图片压缩(利用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);}},
  1. image的加载事件(onload),是在一张图片被完整加载后触发的事件,一般用这个方法加载图片后获取图片的宽和高

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

  • complete是无论img的src是否有值,只要加载完image对象和属性, complete属性就会变成true,
  • 而onload事件需要图片有src并加载完成后,才会触发
  1. 在拍摄图片之后,就用Exif获取图像的原始数据,例如:拍照方向,拍摄事件,ISO感光度,GPS地理位置等数据
    然后使用canvas根据拍照方向在进行调整和压缩

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

    2. 首先在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/

    3. 将获取的拍摄方向存储在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-uploadhttp-request属性,这样就可以覆盖el-upload自带的上传文件方法,然后在提交按钮事件中加入this.$refs.uploadVisitor.submit();代码
手动上传图片即可。
覆盖el-upload自带的上传方法,需要使用FormData对象,然后用$.ajax来提交,这里没有采用这个方法就不贴代码了

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

  1. H5拍照、预览、压缩、上传采坑记录

    H5拍照.预览.压缩.上传采坑记录 公司项目前段时间需要实现手机拍照上传的功能,本来以为用createObjectURL和canvas可以很轻松的实现,结果发现问题多多,特此记录下来. DEMO预览( ...

  2. vue本地上传并预览php,vue.js 实现图片本地预览 裁剪 压缩 上传功能

    以下代码涉及 Vue 2.0 及 ES6 语法. 目标 纯 javascrpit 实现,兼容ie9及以上浏览器,在本地做好文件格式.长宽.大小的检测,减少浏览器交互. 现实是残酷的,为了兼容Ie9 还 ...

  3. 移动端/手机端 完成图片旋转 压缩 剪裁 上传

    本篇文章主要介绍移动端/手机端图片的旋转.压缩.剪裁.上传 这个功能的实现已经好了几次方案流程了,对最终的方案流程进行简述 实现功能的主要方法/思想 1.图片的选取主要是通过input实现 2.图片的 ...

  4. 带图片预览功能的图片上传

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  5. vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决:

    vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决: 参考文章: (1)vue富文本编辑,编辑自动预览,单个图片上传不能预览的问题解决: (2)https://www.cnblogs.co ...

  6. ASP.NET工作笔记之一:图片上传预览及无刷新上传

    转自:http://www.cnblogs.com/sibiyellow/archive/2012/04/27/jqueryformjs.html 最近项目里面涉及到无刷新上传图片的功能,其实也就是上 ...

  7. php 文件预览 水印,PHP图片上传,预览图上传,水印设置

    //设置图片的存放目录 设置水印的存放地址如果愿意,可以给预览图.上传图片分设不同的存储地址 $img_path = $_SERVER['DOCUMENT_ROOT']."/data/img ...

  8. html 上传图片前预览,HTML实现图片上传前预览

    HTML5 Upload #destination{ filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(true,sizingMeth ...

  9. javascript 手机移动端 微信 拍照 录音 录视频并阿里oss上传

    调用照相机,拍照 <input type="file" accept="image/*" capture="camera"> 1 ...

最新文章

  1. 中用BBP公式计算_【真课堂】7年级信息技术:数据计算
  2. Hybris (SAP旗下的软件公司)
  3. Bootstrap插件
  4. 前端学习(2653):对比vue2中的实现
  5. Android动画的实现 上
  6. chrome应用程序无法启动因为并行配置不正确_Win8打不开软件提示并行配置不正确的解决方法...
  7. java 合并csv_用java将三个csv表格文件,整合数据组合成一个文件。
  8. registered php streams sqlsrv,tp5与SQL Server的爱恨情仇(1)
  9. tomcat7不支持html5吗,HTTP状态404说明请求的资源()不可用。的Apache Tomcat/7.0.27
  10. 思科、华为、Dell visio图下载
  11. java自动化开发_五大Java自动化测试框架
  12. 《大数据技术原理与应用》(第三章 HDFS 课后答案)
  13. jovi五子棋下载_五子棋终结者
  14. go与python的前景_为什么说GO语言是未来前景看好的编程语言
  15. 65位高校教师接龙晒工资,全国各地高校,给打算入高校的博士们参考!
  16. 关于enq: US – contention
  17. 打开个税App:竟要补税两万多...
  18. 20220728使用电脑上的蓝牙和汇承科技的蓝牙模块HC-05配对蓝牙串口传输
  19. 如何改变思维导图的导图结构
  20. 职场面试中遇到的问题,八个方案,见招拆招

热门文章

  1. pgpool mysql_pgpool 简明使用教程
  2. basemap画天气图(and风速急流区)
  3. 基于S2SH+ExtJS4+Oracle9i技术实战开发电子商业汇票系统(银行内系统通讯)
  4. MATlAB运用——数值积分
  5. 教大家在网吧上网不用钱的办法
  6. BS1045-基于Android的校园交流信息通讯管理系统
  7. 预习:图书信息管理系统的设计与实现
  8. OneCloud记录
  9. js实现进度条的拖拽
  10. 鼠标右键一直旋转无反应的解决方法