一文了解H5照片上传过程
一、选择拍照或文件
HTML:
使用<input>
标签,
type
设为"file"
选择文件,
a
ccept
设为"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 旋转标志位,判断旋转角度,在画布上对图片进行旋转后,重新导出新的图片即可。
/*** 修正图片旋转角度问题* @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照片上传过程相关推荐
- uni-app uni-file-picker文件上传实现拍摄从相册选择获取图片上传文档服务器(H5上传-微信小程序上传)
前言 最近在使用uni-app写H5移动端,有一个从手机拍摄从相册选择获取图片上传到文档服务器功能. 查阅uni-app发现关于上传图片,uni-file-picker文件上传,uni.chooseI ...
- 安卓h5混合开发照片上传的问题
安卓webview环境下,不能调用html5的照片上传<input type="file">,同时,由于前端页面在安卓环境下的存储容量有限制(有些系统是4M),不考虑把 ...
- H5上传文件又双叒叕开测了!
需求背景:为了方便用户上传自己手机内的本地视频,同时提高视频的分发量,故支持在移动端H5页面增加上传视频.音乐.图片. 原型图: 1.首页&上传素材空页面: 2.上传素材(有素材)&a ...
- H5上传照片、图片及预览裁剪
H5上传照片.图片及预览裁剪 忙里得闲将之前工作中遇到的问题进行总结 要实现该效果主要分三步 一.如何获取图片及照片甚至打开手机摄像头 刚开始做的时候,本人也是一片茫然,怎么获取图片甚至控制摄像机?在 ...
- 智能车自动控制快速停车_控制您的智能手机的自动照片上传
智能车自动控制快速停车 Modern smartphones and cloud photo services want to automatically upload every single ph ...
- 手机怎么录照片上传到抖音短视频,这个必须要知道。
经常玩抖音的朋友可能一直在好奇,有些人上传的并不是连续的视频,而是一张一张的照片,并且照片上还有相应的配文,其实原理和上传的视频是一样的,需要提前将这些图片做成一个图集的视频形式,然后在上传到抖音,那 ...
- Android实现批量照片上传至服务器,拍照或者从相册选择
最近由于项目需求,需要完成批量照片上传,折腾了一段时间,终于完成了,达到了如下效果 主界面主要有GridView组成和按钮组成,当按下一个格点时,会调用相机或者相册,拍照或者选择相册照片,选择完成之后 ...
- 高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:宇的季节 cnblogs.com/chenkeyu/p/80 ...
- cmmi文档_实施CMMI过程改进的框架介绍
已经了解了CMMI实施方法是IDEAL模型,而今天是在IDEAL模型的基础上实施CMMI过程改进的框架,该框架可以很好的帮助大家理解IDEAL模型和CMMI过程改进的核心内容.框架图如下: 框架内容介 ...
最新文章
- 部分小区业主抵制人脸识别:我不在家,你都清楚
- 【转】Nginx服务器的反向代理proxy_pass配置方法讲解
- 前端学习(2156):uglifyjswebpackplugin的使用
- 准确度判断 语义分割_【语义分割】DeepLab v1/v2
- 配置Windows Server 2008群集
- Windows下安装RabbitMQ报错:unable to perform an operation on node时的解决方案
- 《Producter:让产品从0到1》一导读
- Form表单只提交field的值,而不进行页面跳转
- 菜鸟的系统架构师如何应对交易系统激增的系统流量
- 吉林大学计算机学院刘,刘华虓-吉林大学计算机科学与技术学院
- 地面控制点的作用_地下室人防预留预埋施工要点及控制点
- Eclipse快捷键、Debug调试
- msvcr100.dll丢失怎么办?msvcr100.dll丢失的解决方法
- 新版本(2019后)intell idea怎么恢复默认设置
- 佐治亚理工计算机科学录取,佐治亚理工学院计算机科学排名第4(2018年TFE美国排名)...
- 使用wireshark进行安卓抓包分析
- Java联网3D坦克大战(网络编程)
- 白酒行业如何结合互联网模式突破年营业额过亿
- 大疆aeb连拍_不适合航拍?不如深度发掘大疆spark拍照功能
- JavaSE常用类练习