文章目录

前言

一、为什么要压缩图片

二、图片压缩方式

1. 微信小程序​​​​​​​

2. H5

总结


前言

关于微信小程序、H5兼容性问题,今天就压缩以及上传图片做一个可实现方法的简要阐述。


一、为什么要压缩图片​​​​​​​

在使用uni-app开发小程序及H5的具体业务中,我们会遇到需要让用户上传本地图片的场景,随着现在的手机像素越来越高,图片的大小也越来越大,上传原图后一方面是难以上传成功,另一方面是上传成功后在列表中图片太大加载时间过长或者加载失败。若是直接提示用户 “无法上传xxM以上的图片” ,用户体验会不好,于是需要我们对用户上传的图片进行压缩。而不同平台之间压缩图片的方式并不完全兼容,需要提供不同的方法来实现。本文主要记录了在不同平台实现图片压缩上传的其中一种可实现方法。

二、图片压缩方式

uni-app官方提供了关于图片的一系列内置API

首先从选择图片开始

uni.chooseImage(OBJECT)      从本地相册选择图片或使用相机拍照。

// 该方法兼容小程序、H5
uni.chooseImage({count:1,sizeType: ['compressed'],success: res => { // success: 成功则返回图片的本地文件路径列表let size = res.tempFiles[0].size // 选择第一张图片console.log('图片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`)}
})

图片选择完毕,下面就是不兼容的地方了 ⬇️

1. 微信小程序​​​​​​​

小程序压缩图片的方式相对比较简单,不过有一定的局限性,仅对 jpg 格式有效。

uni.compressImage(OBJECT)     压缩图片接口,可选压缩质量。

// 该方法兼容app和小程序,不兼容h5,且仅对jpg格式有效
uni.compressImage({src: src, // 图片路径quality: 10, // 图片压缩质量,0~100,默认80,仅对jpg有效success: res => {console.log(res.tempFilePath,'压缩后的图片路径')// 接下来可以在这里处理图片上传}
})

实现图片上传

uni.getFileSystemManager()     获取全局唯一的文件管理器

readFile()     读取文件,可转换编码格式

// 该方法不兼容h5
uni.getFileSystemManager().readFile({filePath: path, // 要读取的文件路径encoding: 'base64', // 编码格式success: file => {wx_uploadImage({ // 调用接口实现上传图片,使用其他方式也可以image: `data:image/png;base64,${file.data}`}).then(res => {console.log('上传图片成功', res)this.image = res.storage_path // 赋值或者其他操作})}
})

2. H5

H5需要使用另外的方式来压缩图片,这里用到了canvas。

- 分三步 -

1. 使用canvas限制图片大小(压缩图片),并转换为"blob路径";

uni.getImageInfo()     获取图片信息​​​​​​​

uni.getImageInfo({src,success(res) {console.log('压缩前', res);let canvasWidth = res.width; // 图片原始宽度let canvasHeight = res.height; // 图片原始高度console.log('宽度-',canvasWidth,'高度-',canvasHeight);let img = new Image();img.src = res.path;let canvas = document.createElement('canvas');let ctx = canvas.getContext('2d');// 这里根据要求限制图片宽高if (canvasWidth >= 1000) {canvas.width = canvasWidth * .1;} else {canvas.width = canvasWidth;}if (canvasHeight >= 1000) {canvas.height = canvasHeight * .1;} else {canvas.height = canvasHeight;}ctx.drawImage(img, 0, 0, canvas.width, canvas.height);//toBlob()方法创造Blob对象,用以展示canvas上的图片canvas.toBlob(function(fileSrc) {let imgSrc = window.URL.createObjectURL(fileSrc);console.log('压缩后的blob路径', imgSrc);});}
});

2. 将 "blob路径" 转换为 "blob文件"(待会转换base64格式图片需要用到 "blob文件" 的格式)

// 传入blob路径,.then()获取blob文件
httpRequest(src) {let that = thisreturn new Promise((resolve, reject) => {let xhr = new XMLHttpRequest()xhr.open('GET', src, true)xhr.responseType = 'blob'xhr.onload = function (e) {if (this.status == 200) {let myBlob = this.responselet files = new window.File([myBlob],myBlob.type,{ type: myBlob.type }) // myBlob.type 自定义文件名resolve(files)} else {reject(false)}}xhr.send()})
},

3. 将 "blob文件" 转换为 base64格式的图片,最后上传图片。

const fileReader = new FileReader()
fileReader.readAsDataURL(file) // 读取blob类型的图像文件(不是blob路径),读取成功触发onload方法,并得到result(base64格式的图片)
fileReader.onload = (event) => {console.log(fileReader.result,'fileReader.result - base64格式');if (fileReader.result) {// 调用wx_uploadImage接口,图片大小必须是1M以下,否则报错wx_uploadImage({image: fileReader.result}).then(res => {console.log('上传图片成功', res)this.image = res.storage_path})}
}

总结

总结一下以上逻辑经过封装后的完整代码:

// 使用条件编译区分微信小程序、H5的图片压缩上传方式
// 点击上传图片
chooseImage(){uni.chooseImage({count:1,sizeType: ['compressed'],success: res => {let size = res.tempFiles[0].sizeconsole.log('图片大小', size, `${size/1000}KB`, `${size/1000/1000}MB`)let path = this.picture_show = res.tempFilePaths[0] //本地图片路径 - pathlet file = res.tempFiles[0] //本地图片文件 - filelet compressPath = ''console.log(path,'路径');console.log(file,'图片文件');// 先压缩,再转换为base64图片,再上传// #ifdef MP-WEIXINif (size > 1048576) {this.mp_compressImage(path)} else {this.mp_filetobase64(path)}// #endif// #ifdef H5if (size > 1048576) {this.h5_compressImage(path);} else {this.h5_filetobase64(file)}// #endif}})
},// 微信小程序 - 图片压缩方法
mp_compressImage(src) {let _this = this// 该方法兼容app和小程序,不兼容h5,且仅对jpg格式有效uni.compressImage({src: src, // 图片路径quality: 10, // 图片压缩质量,0~100,默认80,仅对jpg有效success: res => {console.log(res.tempFilePath,'压缩后的图片路径')// 接下来可以在这里处理图片上传_this.mp_filetobase64(res.tempFilePath)}})
}// 微信小程序 - 'blob路径'转base64图片的方法
mp_filetobase64(path) {// 该方法不兼容h5uni.getFileSystemManager().readFile({filePath: path, // 要读取的文件路径encoding: 'base64', // 编码格式success: file => {wx_uploadImage({ // 调用接口实现上传图片,使用其他方式也可以image: `data:image/png;base64,${file.data}`}).then(res => {console.log('上传图片成功', res)this.image = res.storage_path // 赋值或者其他操作})}})
}// h5 - 图片压缩方法
h5_compressImage(src) {let _this = this;uni.getImageInfo({src,success(res) {console.log('压缩前', res);let canvasWidth = res.width; // 图片原始宽度let canvasHeight = res.height; // 图片原始高度console.log('宽度-',canvasWidth,'高度-',canvasHeight);let img = new Image();img.src = res.path;let canvas = document.createElement('canvas');let ctx = canvas.getContext('2d');// 这里根据要求限制图片宽高if (canvasWidth >= 1000) {canvas.width = canvasWidth * .1;} else {canvas.width = canvasWidth;}if (canvasHeight >= 1000) {canvas.height = canvasHeight * .1;} else {canvas.height = canvasHeight;}ctx.drawImage(img, 0, 0, canvas.width, canvas.height);//toBlob()方法创造Blob对象,用以展示canvas上的图片canvas.toBlob(function(fileSrc) {let imgSrc = window.URL.createObjectURL(fileSrc);console.log('压缩后的blob路径', imgSrc);// 调用httpRequest方法,把bloburl转换成blob文件_this.httpRequest(imgSrc).then(res => {console.log(res,'成功转换为blob文件');_this.h5_filetobase64(res); // 调用方法,把blob文件转换成base64图片})});}});
}// 传入blob路径,.then()获取blob文件
httpRequest(src) {let that = thisreturn new Promise((resolve, reject) => {let xhr = new XMLHttpRequest()xhr.open('GET', src, true)xhr.responseType = 'blob'xhr.onload = function (e) {if (this.status == 200) {let myBlob = this.responselet files = new window.File([myBlob],myBlob.type,{ type: myBlob.type }) // myBlob.type 自定义文件名resolve(files)} else {reject(false)}}xhr.send()})
},// h5 - 'blob文件'转base64图片的方法
h5_filetobase64(file) {const fileReader = new FileReader()fileReader.readAsDataURL(file) // 读取blob类型的图像文件(不是blob路径),读取成功触发onload方法,并得到result(base64格式的图片)fileReader.onload = (event) => {console.log(fileReader.result,'fileReader.result - base64格式');if (fileReader.result) {// 调用wx_uploadImage接口,图片大小必须是1M以下,否则报错wx_uploadImage({image: fileReader.result}).then(res => {console.log('上传图片成功', res)this.image = res.storage_path})}}
}

uni-app开发微信小程序,H5 关于压缩上传图片的问题相关推荐

  1. uni app 开发微信小程序及上线体验

    uni app 开发微信小程序及上线体验 项目创建及微信小程序AppId的申请 本次开发的是电商类的微信小程序,这里用到的是HBuilderX这个编辑器.之前用的Visual Studio Code ...

  2. 记录uni.app开发微信小程序中地图的使用,以及项目中的解决办法

    标题先讲一下需求:需要获取用户的地址信息以及经纬度,并在地图中展示时出来 uniapp官方也提供了api uni.getLocation(OBJECT) getLocation只能获取用户的经纬度,不 ...

  3. uniapp开发微信小程序/h5完整流程,含vant/uview(h5适配vw)

    theme: smartblue highlight: dark 创建项目 创建后的项目 此处插入一个坑 亦可以使用uniapp vue-cli 创建项目 vue create -p dcloudio ...

  4. 微信小程序wx.canvasToTempFilePath压缩上传图片,ios压缩成功但是数据sm2加密后无法发起请求,安卓一切正常

    问题以及解决: 吐槽遇到的问题~ 在写微信小程序的时候,采用wx.canvasToTempFilePath压缩图片且上传的时候,安卓一切正常,我在开发工具上也一切正常,偏偏ios上就不正常,不正常不是 ...

  5. uni.app开发物联网小程序

    1.当切换页面的时候,容易与mqtt服务器断开连接,并报错 原因:在onLoad事件中,获取参数的时候使用异步获取,但是在事件里面还使用了这个参数,导致mqtt发布的时候,发了一个空主题,导致连接被断 ...

  6. json 微信小程序 筛选_GitHub - zhengyangkang/sl-filter: uni -app 一款使用简单的筛选组件,适配app、微信小程序、H5。...

    sl-filter 筛选 筛选组件,组件名:sl-filter dcloud插件市场地址 sl-filter 简介 一款使用简单的筛选组件,适配app.微信小程序.H5. 感谢分享 效果图 并列菜单 ...

  7. PHP开发B2C商城 微信小程序商城系统源码+数据库,轻量级前后端分离的电商系统,支持微信小程序 + H5+ 公众号 + APP

    项目介绍 一款轻量级.高性能.前后端分离的电商系统,支持微信小程序 + H5+ 公众号 + APP,前后端源码完全开源,看见及所得,完美支持二次开发,可学习可商用,让您快速搭建个性化独立商城. 完整代 ...

  8. uni-app快速开发微信小程序、h5、和app

    过年在家无聊,尝试使用uni-app开发微信小程序,发现这个框架的跨端功能非常强大,几乎能直接从vue移植过来 下面是项目架构图 应用截图 技术栈: 后端 node +mysql 抓取各大视频网站的数 ...

  9. 开发APP、微信小程序、网页,都需要什么?

    开发APP,微信小程序,网页都需要什么? 准备工作 前端开发 后端开发 技术整合 打包上线 结语 在开始介绍之前,我先罗列一下APP,微信小程序,网页的大比较 准备工作 云服务器,域名(需备案),SS ...

  10. uniapp一套代码开发app和微信小程序

    为什么选择uniapp开发? 为什么选择uniapp进行开发? 1.uniapp对于独自开发是相当友好的,一套代码可以兼容app(安卓,ios),小程序,h5等,一定程度上降低了开发的成本,个人开发的 ...

最新文章

  1. oracle用dba登陆怎么登,以SQLDBA身份登录isqlplus
  2. 08-百度ai语音合成
  3. HTTP状态码及含义
  4. Android驱动(1)---Ubuntu中为Android系统上编写Linux内核驱动程序实现方法
  5. MongoDB入门系列(二):Insert、Update、Delete、Drop
  6. android动态设置全屏,Android开发之全屏与非全屏的切换设置方法小结
  7. centos 6.7 openssh 升级到openssh 7.1p
  8. 11. Django基础:应用及分布式路由
  9. MyEclipse中用Maven创建Web项目(亲测有效)
  10. Java后台实现Excel文件下载
  11. Python的伪造数据生成器:Faker
  12. 整理的Android资源代码 源码 整理 Github开源项目下载地址
  13. Excel快捷键(字母+数字)大全
  14. 开发”小米商城官网首页”(静态页面)
  15. python sin_Python数字sin()方法
  16. 程序人生 - 车辆年检与费用你知道多少?
  17. 【安全牛学习笔记】Kali Linux基本工具
  18. 网络适配器突然消失的解决办法
  19. Axure RP 9 for Mac 中文版 专业产品原型设计工具
  20. iPad游戏突然没有声音问题

热门文章

  1. Java实现包含多级目录文件的筛选删除操作
  2. 种子点生长算法(上)——二维种子点生长
  3. 范仲淹写苏州名胜的诗篇
  4. The resource identified by this request is only capable of generating respon
  5. 京东云linux面板脚本,Surge 开启脚本功能后,京东自动签到总结
  6. 机械转行java自学经历,零基础学java,血泪总结的干货
  7. C语言输出各种类型数据的方式
  8. 苏州Uber优步司机奖励政策(8月31日至9月6日)
  9. python 批量转换docx只转换了一个出现pywintypes.com_error被调用的对象已与其客户端断开连接
  10. 如何解决“被调用的对象已与其客户端断开连接“