h5页面使用js实现图片上传(安卓用户也可拍摄、相册二选一)

news/2024/11/8 20:43:28/

思路如下:

使用原生input标签实现图片上传时,如果你的写法是如下所示:

<input type="file" id="upload_file" @change="fileChange($event)" style="display: none" data-type="front"
>
fileChange(el) {if (!el.target.files[0].size) return;let currentType = el.target.dataset.typethis.fileList(el.target.files,currentType);el.target.value = ''
},
// 格式限制
fileList(files,currentType) {for (let i = 0; i < files.length; i++) {
if(files[i].type=='image/jpeg'||files[i].type=='image/jpg'||files[i].type=='image/png'||files[i].type=='image/webp'){this.fileAdd(files[i],currentType);} else {return}}
},
// 获取选择的图片的base64地址
fileAdd(file,currentType) {let reader = new FileReader();reader.vue = this;reader.readAsDataURL(file);let _this = this;reader.onload = function () {file.src = this.result; // 图片的base64地址}
}

那你在手机中表现为:可能部分安卓只能从相册中选择照片,ios则可以拍摄、相册二选一。

为了在安卓手机也可以实现(拍摄、相册二选一)的需求,我们尝试给input标签增加accept="image/*"的属性,然后引出了新的问题

问题描述:发现在部分老机型(2016年买的手机)中当用户拍照后并没有触发input的change事件,网上有讨论说是input的value值没有改变,但如你所见,input标签上我们并没有绑定任何的value值。

最终,因为我们要实现的h5页面仅在微信浏览器环境使用,故我们改成在微信浏览器环境调用wx.chooseImage这个api来实现,关键代码如下所示:

fileClick(type) {var that=thisif(that.supportWxApi) { // 微信环境,用微信提供的apiwx.chooseImage({count: 1, // 最多可以选择的图片张数,默认9sizeType: ['original','compressed'], // 可以指定是原图还是压缩图,默认二者都有'original', 'compressed'sourceType: ['album','camera'], // 可以指定来源是相册还是相机,默认二者都有'album', 'camera'success: function (res) {/*** 获取图片数据*/wx.getLocalImgData({localId: res.localIds[0].toString(),success: function (result) {const localData = result.localData;let imageBase64 = '';if (localData.indexOf('data:image') == 0) {//苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接imageBase64 = localData;} else {//此处是安卓中的坑!在拼接前需要对localData进行换行符的全局替换//此时一个正常的base64图片路径就完美生成赋值到img的src中了imageBase64 = 'data:image/jpeg;base64,' + localData.replace(/\n/g, '');}if(type=='front') {that.compressImg(imageBase64,function(base64Codes){console.log('base64Codes',base64Codes)})} else if(type=='back') {that.compressImg(imageBase64,function(base64Codes){console.log('base64Codes',base64Codes)})}}});}});} else { // 非微信环境,用原生的input上传图片// 用click事件去触发change事件document.getElementById('upload_file').click()}},

图片压缩

服务器那边对图片的大小有要求,故我们利用canvas来实现图片等比例压缩,

压缩图片的关键函数代码如下所示:

            // 图片压缩compressImg(path,callback) {var img = new Image();img.src = path;var objCompressed = {}var _this = this;img.onload = function() {//默认压缩后图片规格var quality = 0.7;var w = this.width;var h = this.height;//实际要求if (w > h) {let scale = h/wh = 1300;w = h/scale;} else {let scale = w/hw = 1300;h = w/scale;}// w = objCompressed.width || w;// h = objCompressed.height || (w / scale);//生成canvasvar canvas = document.createElement('canvas');var ctx = canvas.getContext('2d');// 创建属性节点var anw = document.createAttribute("width");anw.nodeValue = w;var anh = document.createAttribute("height");anh.nodeValue = h;canvas.setAttributeNode(anw);canvas.setAttributeNode(anh);ctx.drawImage(this, 0, 0, w, h);var base64 = canvas.toDataURL('image/jpeg', quality);callback(base64);//回调函数返回base64的值}},

图片压缩函数的使用方式如下:

that.compressImg(imageBase64,function(base64Codes){// imageBase64是压缩前的图片console.log('压缩后的大小:',that.showSize(base64Codes))                                      
})

获取base64图片的大小,返回kb数字

showSize(base64url) {//把头部去掉let str = base64url.replace('data:image/jpeg;base64,', '');// 找到等号,把等号也去掉let equalIndex = str.indexOf('=');if (str.indexOf('=') > 0) {str = str.substring(0, equalIndex);}// 原来的字符流大小,单位为字节let strLength = str.length;// 计算后得到的文件流大小,单位为字节let fileLength = parseInt(strLength - (strLength / 8) * 2);// 由字节转换为kblet size = "";size = (fileLength / 1024).toFixed(2);let sizeStr = size + "";let index = sizeStr.indexOf(".");let dou = sizeStr.substr(index + 1, 2);if (dou == "00") {return sizeStr.substring(0, index) + sizeStr.substr(index + 3, 2)}return size;},

http://www.ppmy.cn/news/768995.html

相关文章

MUI+H5手机上传照片 支持多图片上传和拍照上传

html代码&#xff1a; <header class"mui-bar mui-bar-nav"> <a class"mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> <h1 class"mui-title">拍照 </h1> <a class"mui-icon-right-na…

vue-cute-timeline插件使用

效果 &#xff08;内容覆盖的有些丑&#xff0c;别在意哈&#xff0c;重点是时间线的展示&#xff09;element也有类似的时间线&#xff0c;但是不能使用类似这样的图片 所以就采用了vue-cute-timeline插件 使用方法&#xff08;可自行百度&#xff09; 安装&#xff1a;npm i…

使用css的:before属性在文字前加短竖线

有时候我们需要在文字或者标题前加个短竖线&#xff0c;有的人会使用 border 来模拟一个竖线&#xff0c;其实大可不必&#xff0c;我们可以利用元素的 :before 属性来实现&#xff0c;效果如下&#xff1a; 具体的代码如下&#xff0c; HTML&#xff1a; <span class&quo…

两个人的事情

唔得了。。。。。。我们这里的人了&#xff0c;你好&#xff01;&#xff01;&#xff01;&#xff01;&#xff1f;&#xff01;&#xff1f;&#xff01;&#xff01;&#xff1f;&#xff01;&#xff1f;&#xff01;&#xff1f;&#xff01;我的天啊&#xff01;&#xf…

创新电影院:手机看电影时代已到来

“移动电影院”的发布引发了行业内外的广泛关注。移动电影院是我国电影放映领域的创新尝试&#xff0c;是有别于电影新媒体播放模式&#xff0c;通过手机、平板电脑等移动终端或其可控制的其他设备搭载的移动电影院软件系统作为放映设备&#xff0c;向观众放映已取得《电影片公…

sync-player:使用websocket实现异地同步播放视频

本文作者&#xff1a;星空无限 原文链接&#xff1a;https://liyangzone.com/2020/09/20/%E5%89%8D%E7%AB%AF/sync-player/ GoEasy已获作者授权转载&#xff0c;GoEasy转载时有改动&#xff0c;感谢作者的分享。 前段时间我有这样一个需求&#xff0c;想和一个异地的人一起看电…

新上映的电影不在影院也一样能看到

【新上映的电影不在影院也一样能看到&#xff0c;不要告诉太多人】 来源&#xff1a; ❤林鑫℡的日志 大家都知道&#xff0c;正在电影院上映的电影&#xff0c;大多不允许有网络盗版下载&#xff0c;破坏它票房的。 所以迅雷狗狗会屏蔽这些电影的下载&#xff0c;尽管你搜到了…

Android手机之间实现屏幕共享

已经实现&#xff0c;优化空间还很大。 效果Gif 原理&#xff1a; 方法一&#xff1a;A手机不停的调用系统截图&#xff0c;将得到的数据压缩后不停的Socket发送至服务器&#xff0c;服务器得到数据后推送给B手机&#xff0c;B手机显示图片。 服务器我用nodejs简单写的。 方…