一、选择拍照或文件

HTML:

使用<input>标签,

type设为"file"选择文件,

accept设为"image/*"选择文件为图片类型和相机拍摄,

设置multiple支持多选。

<div class="add-image"><input class="file" type="file" accept="image/*" multiple @change="onFileChange"><div class="add" ><img src="../../assets/add/icon_addphoto.png" alt><p>添加照片</p></div>
</div>

样式:

设置opacity为0,使用自定义div覆盖于上面

.add-image{width: 148px;height: 148px;position: relative;.file{position: absolute;top: 0;left: 0;width: 148px;height: 148px;opacity: 0;}

效果:

二、图片预览

VUE数据驱动更新前端所展示图片

两种方式:

1、使用本地URL(如果项目需要整理服务器图片地址作为表单提交,则本地URL不可以使用,操作删除不便)

URL.createObjectURL方法可创建一个本地的 URL 路径指向本地资源对象,下面使用该接口创建所选图片的地址并展示。

let url=window.URL.createObjectURL(file)
this.goods.goodsImageList.push(url)

2、使用服务器返回路径(缺点:如果上传失败就无法显示)

上传图片请求成功后,服务器返回一个url,使用该url进行字符串拼接,然后加入goods.goodsImageList数组。

三、图片旋转

通过相机拍摄的图片,由于拍摄时手持相机的方向问题,导致拍摄的图片可能存在旋转,需要进行纠正。纠正旋转需要知道图片的旋转信息,这里借助了一个叫 exif-js 的库,该库可以读取图片的 EXIF 元数据,其中包括拍摄时相机的方向,根据这个方向可以推算出图片的旋转信息。
下面是 EXIF 旋转标志位,总共有 8 种,但是通过相机拍摄时只能产生1、3、6、8 四种,分别对应相机正常、顺时针旋转180°、逆时针旋转90°、顺时针旋转90°时所拍摄的照片。

纠正图片旋转角度,只要读取图片的 EXIF 旋转标志位,判断旋转角度,在画布上对图片进行旋转后,重新导出新的图片即可。

/*** 修正图片旋转角度问题* @param {file} 原图片* @return {Promise} resolved promise 返回纠正后的新图片*/
function fixImageOrientation (file) {return new Promise((resolve, reject) => {// 获取图片const img = new Image();img.src = window.URL.createObjectURL(file);img.onerror = () => resolve(file);img.onload = () => {// 获取图片元数据(EXIF 变量是引入的 exif-js 库暴露的全局变量)EXIF.getData(img, function() {// 获取图片旋转标志位var orientation = EXIF.getTag(this, "Orientation");// 根据旋转角度,在画布上对图片进行旋转if (orientation === 3 || orientation === 6 || orientation === 8) {const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");switch (orientation) {case 3: // 旋转180°canvas.width = img.width;canvas.height = img.height;ctx.rotate((180 * Math.PI) / 180);ctx.drawImage(img, -img.width, -img.height, img.width, img.height);break;case 6: // 旋转90°canvas.width = img.height;canvas.height = img.width;ctx.rotate((90 * Math.PI) / 180);ctx.drawImage(img, 0, -img.height, img.width, img.height);break;case 8: // 旋转-90°canvas.width = img.height;canvas.height = img.width;ctx.rotate((-90 * Math.PI) / 180);ctx.drawImage(img, -img.width, 0, img.width, img.height);break;}// 返回新图片canvas.toBlob(file => resolve(file), 'image/jpeg', 0.92)} else {return resolve(file);}});};});
}

四、图片压缩

现在手机拍照质量越来越高,拍出来的照片多达几M甚至十几M,直接上传原图不合理,容易上传失败,且后台对请求体大小有限制,后续加载图片展示也会变得慢,所以要求我们前端在上传之前进行图片的压缩。

下面函数实现了对图片的压缩,原理是在画布上绘制缩放后的图片,最终从画布导出压缩后的图片。方法中有两处可以对图片进行压缩控制:一处是控制图片的缩放比;另一处是控制导出图片的质量。

// 压缩图片
        compressImage(file) {return new Promise((resolve, reject) => {const img = new Image();img.src = window.URL.createObjectURL(file);img.onerror = error => reject(error);img.onload = () => {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');canvas.width = Math.min(img.width, 200);//控制图片大小const radio = canvas.width / img.width; canvas.height = img.height * radio;  //等比缩放ctx.drawImage(img, 0, 0, canvas.width, canvas.height);const quality = 0.8; //控制输出图片质量canvas.toBlob(file => {let files = new window.File([file], 'file.jpg', { type: file.type });resolve(files);}, 'image/jpeg', quality);};});},

这里有个要注意的点,toBlob之后是一个Blob对象,但是请求要求传入file文件,所以我们要将blob对象转为file

    let files = new window.File([this.blob], file.name, {type: file.type})

五、图片上传

通过FormData创建表单数据,发起 ajax POST请求即可,下面函数实现了上传文件。

// 上传图片
        uploadFile(file) {return request({method: 'post',postType: 'file',url: '//...域名.../upload/comments',data: {file: file}});},

export function formData(obj) {let formData = new FormData();Object.keys(obj).forEach(key => {let val = obj[key];val = val == null ? '' : val;if (typeof val === 'object') {if (val instanceof window.File) {formData.append(key, val);} else {formData.append(key, JSON.stringify(val));}} else {formData.append(key, val);}});return formData;
}

export function request(options) {return new Promise((resolve, reject) => {let {method,url,data,params,headers = {},withCredentials = false,// file || ''postType = ''} = options;const xhr = new XMLHttpRequest();let sendData = null;method = (method || 'GET').toUpperCase();const urlParse = /\?/.test(url) ? parseString(url) : {};const querys = { timestamp: Math.round(new Date() / 1000), app_id: values.app_id, ...urlParse, ...params };// 验签let keys = Object.keys(querys);keys.push('app_secret');const api_sign = sha1(keys.sort().map(key => querys[key] || values[key]).join(''));// console.log('api_sign', api_sign);
headers.api_sign = api_sign;url +=(/\?/.test(url) ? '&' : '?') +Object.keys(querys).map(key => `${key}=${escape(querys[key])}`).join('&');xhr.open(method, url, true);// 处理sendData// postType fileif (method === 'POST') {if (postType === 'file') {sendData = data ? formData(data) : null;} else {headers['Content-Type'] = headers['Content-Type'] || 'application/json;charset=UTF-8';sendData = data ? JSON.stringify(data) : null;}}Object.keys(headers).forEach(key => {xhr.setRequestHeader(key, headers[key]);});xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {// options.success(xhr.responseText);let response = {status: xhr.status,data: {}};try {response.data = JSON.parse(xhr.responseText);} catch (e) {console.warn('request error:', e);}if (response) {resolve(response);} else {reject(new Error('cancel by response interceptor'));}}};xhr.onerror = reject;// withCredentials默认为truexhr.withCredentials = withCredentials;// console.log(url, headers, sendData);
        xhr.send(sendData);});
}

六、合并上传

onFileChange(e) {const files = Array.prototype.slice.call(e.target.files);files.forEach(file => {// 本地预览// let url=window.URL.createObjectURL(file)// this.photo.push(url)this.compressImage(file).then(file => {return this.uploadFile(file);}).then(data => {let goodsImage = data.data.data;this.goods.goodsImageList.push(goodsImage);console.log('上传成功');// console.log(this.goods.goodsImageList);}).catch(error => {console.log('上传失败');});});},

最终效果:

转载于:https://www.cnblogs.com/Joe-and-Joan/p/10977887.html

一文了解H5照片上传过程相关推荐

  1. uni-app uni-file-picker文件上传实现拍摄从相册选择获取图片上传文档服务器(H5上传-微信小程序上传)

    前言 最近在使用uni-app写H5移动端,有一个从手机拍摄从相册选择获取图片上传到文档服务器功能. 查阅uni-app发现关于上传图片,uni-file-picker文件上传,uni.chooseI ...

  2. 安卓h5混合开发照片上传的问题

    安卓webview环境下,不能调用html5的照片上传<input type="file">,同时,由于前端页面在安卓环境下的存储容量有限制(有些系统是4M),不考虑把 ...

  3. H5上传文件又双叒叕开测了!

    需求背景:为了方便用户上传自己手机内的本地视频,同时提高视频的分发量,故支持在移动端H5页面增加上传视频.音乐.图片. 原型图: 1.首页&上传素材空页面:     2.上传素材(有素材)&a ...

  4. H5上传照片、图片及预览裁剪

    H5上传照片.图片及预览裁剪 忙里得闲将之前工作中遇到的问题进行总结 要实现该效果主要分三步 一.如何获取图片及照片甚至打开手机摄像头 刚开始做的时候,本人也是一片茫然,怎么获取图片甚至控制摄像机?在 ...

  5. 智能车自动控制快速停车_控制您的智能手机的自动照片上传

    智能车自动控制快速停车 Modern smartphones and cloud photo services want to automatically upload every single ph ...

  6. 手机怎么录照片上传到抖音短视频,这个必须要知道。

    经常玩抖音的朋友可能一直在好奇,有些人上传的并不是连续的视频,而是一张一张的照片,并且照片上还有相应的配文,其实原理和上传的视频是一样的,需要提前将这些图片做成一个图集的视频形式,然后在上传到抖音,那 ...

  7. Android实现批量照片上传至服务器,拍照或者从相册选择

    最近由于项目需求,需要完成批量照片上传,折腾了一段时间,终于完成了,达到了如下效果 主界面主要有GridView组成和按钮组成,当按下一个格点时,会调用相机或者相册,拍照或者选择相册照片,选择完成之后 ...

  8. 高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:宇的季节 cnblogs.com/chenkeyu/p/80 ...

  9. cmmi文档_实施CMMI过程改进的框架介绍

    已经了解了CMMI实施方法是IDEAL模型,而今天是在IDEAL模型的基础上实施CMMI过程改进的框架,该框架可以很好的帮助大家理解IDEAL模型和CMMI过程改进的核心内容.框架图如下: 框架内容介 ...

最新文章

  1. 部分小区业主抵制人脸识别:我不在家,你都清楚
  2. 【转】Nginx服务器的反向代理proxy_pass配置方法讲解
  3. 前端学习(2156):uglifyjswebpackplugin的使用
  4. 准确度判断 语义分割_【语义分割】DeepLab v1/v2
  5. 配置Windows Server 2008群集
  6. Windows下安装RabbitMQ报错:unable to perform an operation on node时的解决方案
  7. 《Producter:让产品从0到1》一导读
  8. Form表单只提交field的值,而不进行页面跳转
  9. 菜鸟的系统架构师如何应对交易系统激增的系统流量
  10. 吉林大学计算机学院刘,刘华虓-吉林大学计算机科学与技术学院
  11. 地面控制点的作用_地下室人防预留预埋施工要点及控制点
  12. Eclipse快捷键、Debug调试
  13. msvcr100.dll丢失怎么办?msvcr100.dll丢失的解决方法
  14. 新版本(2019后)intell idea怎么恢复默认设置
  15. 佐治亚理工计算机科学录取,佐治亚理工学院计算机科学排名第4(2018年TFE美国排名)...
  16. 使用wireshark进行安卓抓包分析
  17. Java联网3D坦克大战(网络编程)
  18. 白酒行业如何结合互联网模式突破年营业额过亿
  19. 大疆aeb连拍_不适合航拍?不如深度发掘大疆spark拍照功能
  20. JavaSE常用类练习

热门文章

  1. JavaScript学习(七)—元素节点的获取方式
  2. python信用评分卡_基于Python的信用评分卡模型分析(二)
  3. RFID 是什么意思
  4. 在私企里,男工人能工作到退休年龄60岁吗?
  5. 普通人买得到国债吗?
  6. 想赚钱广而告之是必不可少的
  7. 如何在今日头条上持续生产优质内容
  8. 家里的网很慢,如何用手机查看都有多少人使用?
  9. 华为手机的硬件好,苹果手机的系统好,能不能将苹果手机的系统装到华为手机里面呢?
  10. 电动汽车真的省钱吗?