目录
uni.createCanvasContext(canvasId,this)
前言:
由于公司业务拓展,急需基于uniapp生成支付宝小程序。之前已经成功将微信小程序和H5融合成一套码,故得知此需求的时候,笔者信心十足,但是本着实践出真知的想法,觉得还是得先调研一下uniapp在支付宝小程序的兼容性,并集成已有项目主体关键功能,为后续的技术调研方案做准备。在调研过程中,发现之前封装好的图片压缩方法在支付宝小程序上无法正常使用,重新阅读了官方文档后,又双更新了项目的图片压缩方法的使用流程。
问题:现有的压缩方案支付宝小程序不生效
之前封装好的压缩方案,原理是使用canvas现实的,但是在支付宝小程序端不生效,canvas相关的api存在但是不可用。
解决方案:
查阅文档后,给canvas添加了id区分支付宝小程序,可兼容之。
以下是官方文档原文
uni.createCanvasContext(canvasId,this)
#定义
画布表示,传入定义在
<canvas/>
的 canvas-id或id(支付宝小程序是id、其他平台是canvas-id)
核心代码展示:
1,封装公用工具类compressImage.js
/**
* 给的文件资源是否小于LimitSize (M),小于走lessCallBack, 大于走moreCallBack
*/
export function imageSizeIsLessLimitSize(imagePath,limitSize,lessCallBack,moreCallBack) {
uni.getFileInfo({
filePath: imagePath,success(res) {
console.log('压缩前图片大小:',res.size / 1024,'kb')
if (res.size > 1024 * 1024 * limitSize) {
moreCallBack()
} else {
lessCallBack()
}
}
})
} // 主调用方法
/**
* 获取小于限制大小的Image,limitSize默认为1M,递归调用。
*/
export function getLessLimitSizeImage(canvasId,imagePath,limitSize = 1,drawWidth,callBack) {
imageSizeIsLessLimitSize(
imagePath,(lessRes) => {
callBack(imagePath)
},(moreRes) => {
uni.getImageInfo({
src: imagePath,success: function(imageInfo) {
var maxSide = Math.max(imageInfo.width,imageInfo.height) //画板的宽高默认是windowWidth
var windowW = drawWidth
var scale = 1
if (maxSide > windowW) {
scale = windowW / maxSide
}
var imageW = Math.floor(imageInfo.width * scale)
var imageH = Math.floor(imageInfo.height * scale)
console.log('调用压缩',imageW,imageH)
getCanvasImage(canvasId,imageH,(pressImgPath) => {
getLessLimitSizeImage(canvasId,pressImgPath,drawWidth * 0.7,callBack)
})
}
})
}
)
}
/**
* 获取画布图片
*/
export function getCanvasImage(canvasId,getImgsuccess) {
const ctx = uni.createCanvasContext(canvasId)
ctx.drawImage(imagePath,imageH)
ctx.draw(false,() => {
uni.canvasToTempFilePath({
canvasId: canvasId,x: 0,y: 0,width: imageW,height: imageH,quality: 1,success(res) {
getImgsuccess(res.tempFilePath)
}
})
})
}
export default {
getLessLimitSizeImage,imageSizeIsLessLimitSize,getCanvasImage
}
2,html调用并上传服务器:
<template>
<view class="upload-page">
<view class="upload-tips">您最多可上传{{maxCount}}张图片</view>
<view class="image-list">
<view v-for="(item,index) in fileList"
:key="index"
class="image-item">
<image class="image"
mode="aspectFit"
:src="item.path"
@click="viewImage(index)"></image>
<image class="image-delete"
:src="imgUrl + 'doctor/img_delete.png'"
@tap.stop="deleteImage"
:data-index="index"></image>
</view>
<view v-if="fileList.length < maxCount"
class="image-item"
@tap="openAlbum">
<image class="image"
:src="imgUrl + 'doctor/img_add.png'"></image>
</view>
</view>
<view class="upload-btn"
@tap="confirmUpload">确定</view>
<canvas canvas-id="pressCanvas"
id="pressCanvas"
class="press-canvas"></canvas>
</view>
</template>
<script>
import { getLessLimitSizeImage } from './compressImage.js'
export default {
data() {
return {
imgUrl: process.env.VUE_APP_RESOURCE_URL,page: {
json: {}
},type: '',fileList: [],maxCount: 9
}
},components: {},props: {},onLoad(options) {
this.type = options.type
this.page.json = options
},methods: {
confirmUpload() {
if (this.fileList.length === 0) {
this.$util.showToast('请至少选择一张图片')
return false
}
this.$Router.back()
uni.$emit(this.page.json.emit,this.fileList)
},// 查看图片
viewImage(index) {
let copyData = [],data = [].concat(this.fileList)
data.forEach((v) => {
copyData.push(v.path)
})
uni.previewImage({
current: copyData[index],urls: copyData
})
},// 删除图片
deleteImage(e) {
let { index } = e.currentTarget.dataset
this.fileList.splice(index,1)
},// 打开相册
openAlbum() {
let length = this.maxCount - this.fileList.length
uni.chooseImage({
count: length,sizeType: ['original','compressed'],sourceType: ['album','camera'],success: (res) => {
this.upLoadImgs(res.tempFilePaths,this.type)
}
})
},// 上传多张图片
upLoadImgs(files,type) {
uni.showLoading()
let promises = files.map((item) => {
return this.uploadImg(item,type)
})
Promise.all(promises)
.then((datas) => {
// 所有上传完成后
this.fileList = datas.length > 0 && this.fileList.concat(datas)
uni.hideLoading()
})
.catch(() => {
uni.hideLoading()
})
},// 上传图片
uploadImg(file,type) {
return new Promise((resolve,reject) => {
getLessLimitSizeImage('pressCanvas',file,1,750,(imagePath) => {
/* #ifdef H5 */
let devicetype = 'h5'
/* #endif */
/* #ifdef MP-WEIXIN */
let devicetype = 'applet'
/* #endif */
/* #ifdef MP-ALIPAY */
let devicetype = 'alipay'
/* #endif */
uni.uploadFile({
url: process.env.VUE_APP_API_URL + 'client/v1/file/images',header: {
'access-token': this.$store.state.user.accessToken,version: process.env.VUE_APP_VERSION,'version-code': process.env.VUE_APP_VERSION_CODE,devicetype: devicetype
},fileType: 'image',filePath: imagePath,name: 'file',formData: {
source: 'inquiryApply',type: ''
},success: (res) => {
let image = JSON.parse(res.data)
console.log('uploadFile success:',image)
if (image.code === 200) {
resolve(image.data[0])
} else {
this.$util.showModal(image.msg || '图片上传失败')
reject(image)
}
},fail: (err) => {
console.log('uploadFile fail:',JSON.stringify(err || {}))
if (err.hasOwnProperty('errMsg') && err.errMsg.indexOf('timeout') > 0) {
this.$util.showModal('上传超时,请稍后再试')
} else {
this.$util.showModal('图片上传失败,请稍后再试')
}
reject(err)
},complete: () => {}
})
})
})
}
}
}
</script>
<style lang="scss" scoped>
.upload-page {
position: relative;
width: 750rpx;
height: 100vh;
background-color: #ffffff;
}
.upload-tips {
width: 750rpx;
height: 80rpx;
background-color: #fffbe8;
font-size: 28rpx;
color: #ed6a0c;
line-height: 80rpx;
text-align: center;
}
.image-list {
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
width: 750rpx;
padding: 30rpx;
}
.image-item {
position: relative;
box-sizing: border-box;
width: 210rpx;
height: 210rpx;
margin-right: 30rpx;
margin-bottom: 30rpx;
border: 1rpx solid #ebedf0;
}
.image-item:nth-child(3n) {
margin-right: 0;
}
.image-item .image {
width: 210rpx;
height: 210rpx;
}
.image-item .image-delete {
position: absolute;
top: -30rpx;
right: -30rpx;
width: 40rpx;
height: 40rpx;
padding: 10rpx;
}
.upload-btn {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
height: 100rpx;
background-color: $primary;
font-size: 30rpx;
color: #ffffff;
line-height: 100rpx;
text-align: center;
}
.press-canvas {
position: absolute;
top: -1000px;
left: -1000px;
background-color: gray;
width: 750px;
height: 750px;
}
</style>
小结:
以上就是笔者分享的图片压缩上传的方法封装及使用啦,完美兼容支付宝小程序,微信小程序及H5三端。希望对大家有所帮助。如有错误希望各位大神多多指教。
原文地址:https://blog.csdn.net/m0_61243965
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。