0 前言
微信小程序中,上传图片,如标题,涉及图片选择、图片转码、图片压缩、图片预览、图片上传等
1 图片选择
需要使用微信提供的wx.chooseMedia
chooseImage() {var that = thiswx.chooseMedia({count: 1,mediaType: ['image'],//图片尺寸原图和压缩图// sizeType: ['original', 'compressed'],//从相册选图和使用相机sourceType: ['album', 'camera'],camera: 'back',success(res) {// tempFilePath可以作为img标签的src属性显示图片const tempFilePaths = res.tempFiles[0].tempFilePath// 图片压缩var compressFilePath = that.get_img(tempFilePaths)that.setData({photo: compressFilePath})}})},
2 图片压缩
在wxml中放置一个canvas,使用canvas来实现图片的压缩
<!--wxml--><canvas style="width: {{cwidth}}px;height: {{cheight}}px;" canvas-id="myCanvas" class="canvas-compress"></canvas>
让canvas在画面外
/*wxss*/.canvas-compress {position: absolute;top: -1000px;background-color: #bbbbbb;}
进行图片的压缩
//jsget_img(url) {let that = thisconsole.log("选择图片返回的路径", url)that.setData({uploadShow: false,loadingShow: true})wx.getImageInfo({src: url,success(res) {console.log(res)console.log("路径", res.path)console.log('获得原始图片大小', res.width, res.height)var originWidth, originHeight;originHeight = res.height;originWidth = res.width;// 最大尺寸限制 //压缩比例var maxWidth = originWidth >= originHeight ? 800 : 1600,maxHeight = originWidth >= originHeight ? 1600 : 800;// 目标尺寸var targetWidth = originWidth,targetHeight = originHeight;//等比例压缩,如果宽度大于高度,则宽度优先,否则高度优先if (originWidth > maxWidth || originHeight > maxHeight) {if (originWidth / originHeight > maxWidth / maxHeight) {// 要求宽度*(原生图片比例)=新图片尺寸targetWidth = maxWidth;targetHeight = Math.round(maxWidth * (originHeight / originWidth));} else {targetHeight = maxHeight;targetWidth = Math.round(maxHeight * (originWidth / originHeight));}}console.log("压缩后的图片大小", targetWidth, targetHeight)var ctx = wx.createCanvasContext('myCanvas');ctx.clearRect(0, 0, targetWidth, targetHeight);ctx.drawImage(res.path, 0, 0, targetWidth, targetHeight);ctx.draw();//更新canvas大小that.setData({cwidth: targetWidth,cheight: targetHeight});setTimeout(function () {wx.canvasToTempFilePath({canvasId: 'myCanvas',success: (res) => {console.log("压缩后的临时路径:", res.tempFilePath)// file格式转base64格式return that.imgBase64(res.tempFilePath)},fail: (err) => {console.error(err)}}, that)}, 400); //延迟400毫秒为了等canvas画上}})},
注意,此处调用的微信的canvas相关的方法,有些是落后的,但是要改造的话涉及的变动量比较大,所以就没有修改了
3 图片转码
将base64图片转为File文件类型
//jsimgBase64(img_url) {let res = wx.getFileSystemManager().readFileSync(img_url, 'base64')this.setData({photo: res})this.setData({loadingShow: false,successShow: true})return res},
将base64图片转为File文件类型(如果你需要的话)
// 将base64图片转为File文件类型base64ToFile(base64data, cb) {const fsm = wx.getFileSystemManager();const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];if (!format) {return (new Error('ERROR_BASE64SRC_PARSE'));}const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;const buffer = wx.base64ToArrayBuffer(bodyData);fsm.writeFile({filePath,data: buffer,encoding: 'binary',success() {console.log('文件地址')console.log(filePath)cb(filePath);wx.uploadFile({filePath: filePath,name: FILE_BASE_NAME,url: 'url',})},fail() {return (new Error('ERROR_BASE64SRC_WRITE'));}})},
4 图片上传
直接base64字符串上传即可
5 其他补充
图片上传、加载、完成的相关xwml代码
<van-cell><!-- 图片上传 --><view class="photo-upload-wrap" wx:if="{{uploadShow}}"> <van-icon name="photograph" class="photo-icon" bind:tap="chooseImage"/></view><!-- 图片加载 --><view class="photo-loading-wrap" wx:if="{{loadingShow}}"><van-loading type="spinner" lass="shade" color="#1989fa"></van-loading></view><!-- 图片完成 --><view class="photo-success-wrap" wx:if="{{successShow}}"><van-imagewidth="620rpx"height="400rpx"fit="contain"src="data:image/png;base64,{{photo}}"bind:tap="onClickShow"/><van-icon bind:tap="deletePhoto"class="photo-cancel-icon" name="clear" /></view></van-cell><!-- 图片预览 --><van-overlay show="{{ showPhotoOverlay }}" bind:click="onClickHide"><view class="over-wrapper"><van-imagefit="contain"src="data:image/png;base64,{{photo}}"/></view></van-overlay>
6 参考
微信小程序文件上传file
小程序baes64转普通格式
微信小程序 图片和base64相互转换
微信小程序(组件)----上传单张图片以及获取图片【wx.chooseMedia wx.uploadFile】