一、背景
最近有个需求,需要用户按比例上传图片,即需要在上传前,让用户手动对图片进行裁剪。
看到这个诉求,我就去扒微信的api,发现有个属性叫wx.cropImage是做图片裁剪的,且可以传入对应的裁剪比例。在介入开发后才发现,这个是小程序的api,而非微信公众号的。阅读文档发现,小程序和微信公众号中都有一个叫chooseImage的api,但是返回的数据却不一样,小程序大家开发的都比较多了。本篇文章主要给大家讲一下公众号的图片裁剪&上传,实现效果如下图:
二、图片选择
选择图片使用chooseImage这个api,具体使用如下所示。选择成功后,返回localIds,是选定照片的本地ID列表,注意这个和小程序是不同的。
wx.chooseImage({count: 1, // 默认9sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有success: (res)=> {let localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片}
});
三、预览图片
wx.previewImage({current: '', // 当前显示图片的http链接urls: [] // 需要预览的图片http链接列表
});
四、获取本地图片
通过chooseImage拿到本地图片id 列表后,那么如何获取到图片呢。毕竟我们也没有办法直接使用图片id进行上传等交互。这个时候就引入了新的api,即:getLocalImgData。该api就是通过图片的localID,来获取图片的base64数据。拿到该数据后,就可以和后端接口进行交互了。
wx.getLocalImgData({localId: '', // 图片的localIDsuccess: function (res) {var localData = res.localData; // localData是图片的base64数据,可以用img标签显示}
});
五、上传图片
wx.uploadImage({localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得isShowProgressTips: 1, // 默认为1,显示进度提示success: function (res) {var serverId = res.serverId; // 返回图片的服务器端ID}
});
六、图片裁剪
上述我们得知,微信公众号是没有裁剪api的,那么我们只能通过三方插件来实现裁剪功能。
这里我使用到的插件是vue-cropper
插件:GitHub - xyxiao001/vue-cropper: A simple picture clipping plugin for vue
1、安装
yarn add vue-cropper
2、组件封装
组件具体的使用,我这里就不赘述了,上述github上有详细的使用文档。我这里贴下我封装组件的代码吧。
<template><div class="home"><div class="cropper"><vueCropperref="cropper":img="image":outputSize="option.outputSize":outputType="option.outputType":canScale='option.canScale':autoCrop='option.autoCrop':autoCropWidth='option.autoCropWidth':autoCropHeight='option.autoCropHeight':canMoveBox='option.canMoveBox':canMove='option.canMove':centerBox='option.centerBox':info='option.info':fixedBox='option.fixedBox'@realTime='realTime'></vueCropper></div><div class="btn"><van-button type='default' style="margin-right: 20px;" size="small" @click='cancel'>取消</van-button><van-button type='primary' size="small" @click='handleClick'>确定</van-button></div></div>
</template>
<script>
import { VueCropper } from "vue-cropper";
export default {props: {image:[String, Array]},data() {return {option: {outputSize: 1, // 裁剪生成图片质量outputType: "jepg", // 裁剪生成图片格式canScale: true, // 图片是否允许滚轮播放autoCrop: true, // 是否默认生成截图框 falseinfo: false, // 是否展示截图框信息autoCropWidth: 300, // 生成截图框的宽度autoCropHeight: 200, // 生成截图框的高度canMoveBox: true, // 截图框是否可以拖动fixedBox: true, // 固定截图框的大小canMove: false, // 上传图片是否可拖动centerBox: true, // 截图框限制在图片里面},previewImg: null, // 预览后的图片previewObj: {width: 200,height: 200,},imgObj: {width: 500,height: 500,},};},components: {VueCropper,},methods: {cancel(){this.$emit('cancel')},handleClick() {this.$refs.cropper.getCropData((data) => {this.$emit('afterCropImage',data)});},},mounted() {},
};
</script>
<style scoped>
.home {width: 100%;height: 100%;background-color: #eee;}
.cropper {width: 100%;height: 80%;border: 1px solid orange;
}
.btn{text-align: center;margin-top: 10px;
}
</style>
上述代码就可以实现图片的裁剪,具体的样式可以自己进行调整。props中的image可以传入base64的图片数据。
如果需要对剪切的图片进行实时预览,可以加入以下代码:
realTime(data) {const that = this;this.$refs.cropper.getCropBlob((data) => {this.blobToDataURI(data, function(res) {console.log(res);that.previewImg = res;});});},blobToDataURI(blob, callback) {var reader = new FileReader();reader.readAsDataURL(blob);reader.onload = function(e) {callback(e.target.result);};},
七、微信公众号实现图片选择&裁剪&上传
接下来就是重点部分了,这里我只提供核心代码进行参考哈。
1、组件使用
<van-popup v-model="isShow" :style="{ height: '100%',width: '100%' }"><VueCropper ref="vueCropper" :image="image" @afterCropImage="afterCropImage" /></van-popup>
2、js代码,实现图片选择&裁剪&上传
chooseImg() {window.wx.chooseImage({count:1,sizeType: ['compressed'],sourceType: ['album', 'camera'],success: function (res) {this.getImgData(res.localIds)}})} getImgData(localId) {window.wx.getLocalImgData({localId: localId,success: async (res)=> {let base64 = res.localDatalet localData = base64;localData = localData.replace(/\r|\n/g,"").replace("data:image/jgp", "data:image/jpeg");this.isShow = true // 此处把组件显示出来this.image = localData // image为传入组件内的土拍呢数据},fail () {reject(new Error('getLocalImgData 调用失败'))}})
} afterCropImage(base64){this.isShow = false // 关闭裁剪组件this.uploadBase64(base64)}, uploadBase64(){// 上传,业务代码这里不做展示了,自定义即可}
以上就是全部的内容了,感觉公众号实现该功能的相关文档比较少,所以写篇文章进行记录。有疑问欢迎留言交流~~~~~~
微信文档链接:概述 | 微信开放文档