webAPP如何实现移动端拍照上传(Vue组件示例)()

【webAPP如何实现移动端拍照上传(Vue组件示例)()】大道之行,天下为公。这篇文章主要讲述webAPP如何实现移动端拍照上传(Vue组件示例)?相关的知识,希望能为你提供帮助。
摘要:使用html5编写移动Web应用,主要是为了尝试一下“一套代码多处运行”,一个webapp几乎可以不加修改的运行在PC/android/ios等上面运行。但是写到现在觉得虽然这种方式弊大于利,不仅在速度上有差异,webapp对移动端的一些原生功能支持并没有那么好。我用的vue写的系统,完成之后用webpack打包模块,hbuilder打包成apk,但是要解决的问题并不少。现在来说说webapp拍照上传。
html5是支持拍照上传或者调用本地相册的,

< !--兼容安卓微信调用摄像头--> < input type="file" name="file"capture="camera"> < !--兼容安卓默认选择sd卡上的相册图片--> < input type="file" name="file" accept="image/*" >

然而hbuilder打包apk之后,在安卓机(华为荣耀9)测试的时候,发现    capture="camera" 失效了,打开的是本地相册,但是不能调用摄像头。我就打开了webpack-server,移动端的浏览器运行的时候,在浏览器里面是可以调用摄像头的,最后发现了很多人都有这个问题,但是并没有说明解决办法。我自己最后是结合H5提供的 window.plus 功能调用移动端的摄像头,当然,先判断移动端是否支持 window.plus ,如果不支持,就依然用 < input> 实现图片选取。
H5 的 plus.camera 官方 API:http://www.html5plus.org/doc/zh_cn/camera.html
下面我就说说我的解决方法,主要是参照了网上一些实例和官网API写出来的,请看下面的VUE组件,这个组件可以直接引用,有兴趣的同学可以试试:
1 < template> 2< div> 3< div class="camera-photo" ref="divGenres" v-show="isPhoto" @click="choiceImg"> 4< img style="width:300px; height:300px; " src="http://img.readke.com/220504/034FLB7-0.jpg quality=100& size=b4000_4000& sec=1528077222& di=69a2ffcffd12e35216ab71da7a610abe& src=http://img.zcool.cn/community/[email  protected]"/> 5< br> 6< span> 请选择图片上传< /span> 7< input type="file" ref="uploadImage" @change="onFileChange" accept="image/*" capture="camera" style="display: none; "> 8< /div> 9 10< div class="list-li" v-show="show"> 11< div style="display: inline-block; "> 12< a class="list-link" @click=‘previewImage(imgsrc)‘> 13< img :src="https://www.songbingjia.com/android/imgsrc"> 14< /a> 15< span class="list-img-close" @click=‘delImage‘> < /span> 16< /div> 17< div class="add-preview" v-show="isPreview" @click="closePreview"> 18< img :src="https://www.songbingjia.com/android/previewImg"> 19< /div> 20< button type="button" class="upload-button" @click="upload"> 图片上传< /button> 21< /div> 22< /div> 23 < /template> 24 25 < script> 26import Bus from ‘../bus.js‘ 27import qs from "qs" 28export default { 29data(){ 30return{ 31imgsrc:‘‘,//上传的·图片的地址 32show:false,//图片放大预览 33previewImg: ‘‘,//预览图片的地址 34isPreview: false,//是否预览当前图片 35isPhoto: true, 36uploadFile:null 37} 38}, 39methods:{ 40 41choiceImg(){ 42let self = this; 43if (!window.plus){ 44self.addPic()//如果不支持plus,就用本地相册上传即可 45return; 46} 47 48let title = "选择照片" 49let btns = [‘拍照‘,‘相册‘] 50 51var func = function(e){ 52var index = e.index; 53 54if(index == 1) self.choiceCamera(); 55if(index == 2) self.choicePic(); 56} 57 58if(title & & btns & & btns.length > 0){ 59var btnArray = []; 60for(var i=0; i< btns.length; i++){ 61btnArray.push({title:btns[i]}); 62} 63 64plus.nativeUI.actionSheet({ 65title : title, 66cancel : ‘取消‘, 67buttons : btnArray 68}, function(e){ 69if(func) func(e); 70}); 71} 72}, 73 74choiceCamera(){ 75let self = this; 76var cmr = plus.camera.getCamera(); 77cmr.captureImage(function (path){ 78 79plus.io.resolveLocalFileSystemURL(path, function(entry){ 80self.imgsrc= https://www.songbingjia.com/android/entry.toLocalURL(); 81self.show = true; 82 83}, function(e){plus.nativeUI.toast("读取拍照文件错误:" + e.message); }); 84}, function(e){},{index:1,filename:"_doc/camera/"}); 85} , 86 87choicePic(){ 88let self = this; 89plus.gallery.pick( function(p){ 90plus.io.resolveLocalFileSystemURL(p, function(entry) { 91self.imgsrc= https://www.songbingjia.com/android/entry.toLocalURL(); 92self.show = true; 93}, function(e) { 94plus.nativeUI.toast("读取拍照文件错误:" + e.message); 95}); 96}, function ( e ) {plus.nativeUI.toast("读取拍照文件错误:" + e.message); }, { 97filename: "_doc/camera/", 98filter:"image" 99} ); 100}, 101 102upload(){ 103var self = this 104var wt ; 105if (window.plus) 106wt = plus.nativeUI.showWaiting(); 107 108var img = new Image, 109width = 512, //image resize压缩后的宽 110quality = 0.5, //image quality压缩质量 111canvas = document.createElement("canvas"), 112drawer = canvas.getContext("2d"); 113img.src = https://www.songbingjia.com/android/self.imgsrc; 114img.onload = function(){//利用canvas压缩图片 115canvas.width = width; 116canvas.height = width * (img.height / img.width); 117drawer.drawImage(img, 0, 0, canvas.width, canvas.height); 118var base64 = canvas.toDataURL("image/*", quality); 119var pic = base64.split(‘,‘)[1]; //图片的base64编码内容 120var f=self.imgsrc; 121var filename=f.replace(f.substring(0, f.lastIndexOf(‘/‘) + 1), ‘‘); //图片名称 122 123if(self.uploadFile !== null){//addPic方法得到的图片文件 124filename =self.uploadFile.name 125let reader = new FileReader(); 126reader.readAsDataURL(self.uploadFile); 127reader.onload = function(e){ 128img.src = https://www.songbingjia.com/android/e.target.result; 129} 130img.onload = function(){ 131canvas.width = width; 132canvas.height = width * (img.height / img.width); 133drawer.drawImage(img, 0, 0, canvas.width, canvas.height); 134base64 = canvas.toDataURL("image/*", quality); 135pic = base64.split(‘,‘)[1]; 136} 137}
//此处是将图片上传到服务器的代码,略过 138} 139}, 140 141onFileChange(e){ 142let self = this; 143let files = e.target.files || e.dataTransfer.files; 144if (!files.length) return; 145let file = files[0]; //File对象 146self.uploadFile = file; 147let reader = new FileReader(); //FileReader对象 148reader.readAsDataURL(file); //该方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,readyState 会变成已完成(DONE),并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。 149 150reader.onload = function(e){ 151self.imgsrc= https://www.songbingjia.com/android/e.target.result; //图片内容的base64编码 152self.show = true; 153} 154}, 155 156addPic: function (e) { 157let els = this.$refs.divGenres.querySelectorAll(‘input[type=file]‘) 158els[0].click() 159return false 160}, 161 162delImage: function () { 163this.imgsrc =""; 164this.show = false; 165this.isPreview = false; 166}, 167 168previewImage: function (url) { 169let vm = this; 170vm.isPreview = true; 171vm.previewImg = url; 172}, 173 174closePreview: function () { 175let vm = this; 176vm.isPreview = false; 177vm.previewImg = ""; 178}, 179}, 180 } 181 < /script> 182 183 < style> 184.upload-button{ 185display: block; 186margin-top: 10px; 187} 188.camera-photo{ 189text-align:center; 190margin-top:80px; 191} 192.list-li { 193 194display: flex; 195flex-direction: column; 196align-items: center; 197padding: 8px; 198margin-top:10px; 199position: relative; 200text-align: center; 201margin-left: auto; 202margin-right: auto; 203top: 0; 204left: 0; 205right: 0; 206bottom: 0; 207} 208.list-link img { 209width: 150px; 210height: 150px; 211} 212.list-link a:visited { 213background-color: #465c71; 214border: 1px #4e667d solid; 215color: #dde4ec; 216display: flex; 217line-height: 1.35em; 218padding: 4px 20px; 219text-decoration: none; 220white-space: nowrap; 221overflow: hidden; 222} 223.list-link a:hover { 224background-color: #bfcbd6; 225color: #465c71; / 226text-decoration: none; 227} 228.list-link a:active { 229background-color: #465c71; 230color: #cfdbe6; 231text-decoration: none; 232} 233.list-img-close { 234background: #ffffff url(https://timgsa.baidu.com/timg?image& quality=80& size=b9999_10000& sec=1526905315674& di=4c2d6a6985b34e141f37bc9fae7f2209& imgtype=0& src=https://www.songbingjia.com/android/http%3A%2F%2Fpic.58pic.com%2F58pic%2F15%2F55%2F73%2F39I58PICCqK_1024.png) no-repeat right top; 235border-color: #ff4a00; 236background-position: center; 237background-size: 35px 35px; 238display: block; 239float: left; 240top: 5px; 241width: 10px; 242height: 10px; 243position: absolute; 244margin-top: 0px; 245margin-left: 135px; 246padding: 8px; 247z-index: 10; 248border-radius: 5px; 249text-align: center; 250} 251.add-preview{ 252width: 300px; 253height: 300px; 254} 255.add-preview img{ 256width: 100%; 257height: 100%; 258} 259 < /style>

总之,尝试之后觉得,web工程师如果要做移动端开发,还是得有安卓或者ios工程师的支持。
 


    推荐阅读