目录
前言:
问题:现有的压缩方案支付宝小程序不生效
解决方案:
(canvasId, this)
核心代码展示:
1,封装公用工具类
2,html调用并上传服务器:
小结:
前言:
由于公司业务拓展,急需基于uniapp生成支付宝小程序。之前已经成功将微信小程序和H5融合成一套码,故得知此需求的时候,笔者信心十足,但是本着实践出真知的想法,觉得还是得先调研一下uniapp在支付宝小程序的兼容性,并集成已有项目主体关键功能,为后续的技术调研方案做准备。在调研过程中,发现之前封装好的图片压缩方法在支付宝小程序上无法正常使用,重新阅读了官方文档后,又双更新了项目的图片压缩方法的使用流程。
问题:现有的压缩方案支付宝小程序不生效
之前封装好的压缩方案,原理是使用canvas现实的,但是在支付宝小程序端不生效,canvas相关的api存在但是不可用。
解决方案:
查阅文档后,给canvas添加了id区分支付宝小程序,可兼容之。
以下是官方文档原文
(canvasId, this)
#定义
画布表示,传入定义在
<canvas/>
的 canvas-id或id(支付宝小程序是id、其他平台是canvas-id)
核心代码展示:
1,封装公用工具类
-
/**
-
* 给的文件资源是否小于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,
-
limitSize,
-
(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, imagePath, imageW, imageH, (pressImgPath) => {
-
getLessLimitSizeImage(canvasId, pressImgPath, limitSize, drawWidth * 0.7, callBack)
-
})
-
}
-
})
-
}
-
)
-
}
-
/**
-
* 获取画布图片
-
*/
-
-
export function getCanvasImage(canvasId, imagePath, imageW, imageH, getImgsuccess) {
-
const ctx = uni.createCanvasContext(canvasId)
-
ctx.drawImage(imagePath, 0, 0, imageW, 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=""
-
@click="viewImage(index)"></image>
-
<image class="image-delete"
-
:src="imgUrl + 'doctor/img_delete.png'"
-
@="deleteImage"
-
:data-index="index"></image>
-
</view>
-
<view v-if=" < 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 './'
-
-
-
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三端。希望对大家有所帮助。如有错误希望各位大神多多指教。