很多时候我们都会碰到小程序上传图片时因为图片过大而导致请求失败,同时出现各种各样的问题,那么今天来给大家写一个微信小程序上传图片过大导致请求失败的完美解决办法。
以云开发小程序图片检测为例,如果图片过大就会出现以下报错:
<'errCode': -404012, 'errMsg': 'cloud.callFunction:fail error while waiting for the result; at cloud.callFunction api;>
图片过大,所以应该压缩图片
官方给出了一个 wx.compressImage接口用于压缩图片,该接口在开发工具和ios系统都表现良好,但是却在安卓机上几乎没有一点效果,所以这个方案被迫放弃了。于是在网上看到了另一种压缩思路,通过canvas绘制压缩图片,canvas在一般小程序中通常用于海报的生成,我们就是通过这种方式生成一张比原图要小的图片,这样就可以起到压缩效果了。
创建一个canvas标签
这个需要在wxml中创建,不然没有画布,就没办法进行绘图了,代码如下:
<canvas canvas-id="canvas" style="width:{
{cWidth}}px;height:{
{cHeight}}px; position: absolute;left:-1000px;top:-1000px;">canvas>
因为该canvas并不需要显示在页面上,所以我们把他写在了页面之外,其中cWidth和cHeight分别是画布的宽和高,因为图片的比例不一,所以这里采用动态数据,这样可以保证图片的等比例缩放。
编写压缩图片函数
下面的函数是在网上看到的一个版本,觉得挺好的,就直接放出来给大家学习一下,也可以直接调用。
compressImg: function(e) {
var that = this;
console.log(e)
wx.getImageInfo({
src: e,
success: function(res) {
//---------利用canvas压缩图片--------------
var ratio = 2;
var canvasWidth = res.width //图片原始长宽
var canvasHeight = res.height
while (canvasWidth > 200 || canvasHeight > 200) { // 保证宽高在200以内
canvasWidth = Math.trunc(res.width / ratio)
canvasHeight = Math.trunc(res.height / ratio)
ratio++;
}
that.setData({
cWidth: canvasWidth,
cHeight: canvasHeight
})
var ctx = wx.createCanvasContext('canvas')
ctx.drawImage(res.path, 0, 0, canvasWidth, canvasHeight)
ctx.draw(false, setTimeout(function() {
wx.canvasToTempFilePath({
canvasId: 'canvas',
destWidth: canvasWidth,
destHeight: canvasHeight,
quality: 0.3, // 压缩倍率
success: function(res) {
console.log(res.tempFilePath) //压缩过后的最终图片路径
},
fail: function(res) {
console.log(res.errMsg)
}
})
}, 100))
},
fail: function(res) {
console.log(res.errMsg)
}
})
},
通过该函数压缩后,图片大小将大大减小,还可以通过控制canvasWidth来改变压缩的比例,就是代码块中的200,还想更小就把200减小,大点,就增大。
通过这样的方式可以把原本几M的文件,压缩到小于100K,这样在请求上传中,都不会在出现微信小程序上传图片过大导致请求失败的现象了。