Vue页面调用微信API上传图片

由于原生input上传图片无法在选择图片时控制选择的张数,所以选择调用微信JSSDK提供的方法调用相册选择图片进行上传。选择图片后上传到微信服务器,然后通知后台去微信服务器下载到本地服务器。因为需要又要限制选择图片的大小,直接上代码。首选要通过微信公众号appid等参数配置使用微信API权限。

//选择图片方法
chooseImage(){
	return new Promise((resolve, reject)=>{
	  let chooseCount = 9;//最大只能设置为9
	  wx.chooseImage({
	    count: chooseCount, // 默认9
	    sizeType: ['compressed'], // 可以指定是原图还是压缩图,默认二者都有
	    sourceType: ['album','camera'], // 可以指定来源是相册还是相机,默认二者都有
	    success: function (res) {
	      let localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
	      _this.localIds = res.localIds;
	      let localIdsLen = localIds.length;
	      //以下通过localId获取对应的base64,通过计算获取图片大小
	      let i = 0;
	      function getLocalImgDataWX() {
	        wx.getLocalImgData({
	          localId:localIds[i],
	          success:function(response){
	            let localData = response.localData;
	            if (localData.indexOf('data:image') != 0) {
	              //判断是否有这样的头部
	              localData = 'data:image/jpeg;base64,' +  localData
	            }
	            //第一个替换的是换行符,第二个替换的是图片类型,因为在IOS机上测试时看到它的图片类型时jgp,
	            //这不知道时什么格式的图片,为了兼容其他设备就把它转为jpeg
	            localData = localData.replace(/\r|\n/g, '').replace('data:image/jgp', 'data:image/jpeg');
	            let itemSize = _this.getImgByteSize(localData);//获取base64大小
	            _this.imgSize.push(itemSize);
	            i++;
	            if(i < localIdsLen){
	              getLocalImgDataWX();
	            } else {
	              resolve("结束了");
	            }
	          },
	          fail: function (res) {
	            _this.$vux.toast.show({
	              type: "text",
	              width: '20em',
	              text: JSON.stringify(res)
	            });
	            resolve("getLocalImgDataFail");
	          }
	        });
	      }
	      getLocalImgDataWX();
	    },
	    fail: function (res) {
	      _this.$vux.toast.show({
	        type: "text",
	        width: '20em',
	        text: JSON.stringify(res)
	      });
	      resolve("chooseImageFail");
	    }
	  });
	})
}
//选择图片并判断大小
async chooseImageBox(){
  let n = await this.chooseImage();
  if(n.indexOf("Fail") !== -1){
    this.$vux.toast.show({
      type: "text",
      width: '12em',
      text: '图片选择报错,请稍后重试!'
    });
    return;
  }
  for(var j = 0 ; j < this.imgSize.length ; j++){
    if(this.imgSize[j]<100000){
      this.$vux.toast.show({
        type: "text",
        width: '12em',
        text: '图片大小必须在100k以上'
      });
      this.imgSize = [];
      return
    }
    if(this.imgSize[j]>=5120000){
      this.$vux.toast.show({
        type: "text",
        width: '12em',
        text: '图片大小必须在5M以下'
      });
      this.imgSize = [];
      return
    }
  }
  if(this.imgSize.length>0){
  	//上传到微信服务器
    await this.uploadImageWX(this.localIds);
    this.imgSize = [];
  }
}
//获取base64大小
getImgByteSize(data) {
  let size = 0
  if (data) { // 获取base64图片byte大小
    const equalIndex = data.indexOf('='); // 获取=号下标
    if (equalIndex > 0) {
      const str = data.substring(0, equalIndex); // 去除=号
      const strLength = str.length;
      const fileLength = strLength - (strLength / 8) * 2; // 真实的图片byte大小
      size = Math.floor(fileLength); // 向下取整
    } else {
      const strLength = data.length;
      const fileLength = strLength - (strLength / 8) * 2;
      size = Math.floor(fileLength); // 向下取整
    }
  }
  return (size * 1.657)
},

在开发到真机测试的过程中也是遇到了很多问题:
1、计算后的图片大小和真实的图片大小不一致,判断并不准确,不知道是wx.getLocalImgData返回的base64不准确还是通过base64计算图片大小的方法和真实图片大小有很大的误差(目前还未找到答案)。最后通过大量的测试,粗略的估算出真实的图片大小和计算出的图片大小比例在1.657左右。
2、后端在去微信服务器下载图片的过程中,有时图片下载完会解析失败(javax.net.ssl.SSLException: SSL peer shut down incorrectly)目前发现当图片太大时就会解析失败,所以在选择图片的时候默认选择的是压缩图。
3、通过wx.getLocalImgData获取的base64有时会缺失一部分,当做url显示的时候显示不全,怀疑这也是导致后台解析图片失败的原因。

以上三个大问题并没有找到合理的答案和解释,希望有人帮忙解答一下。
上面的方法可能不是最好的方法,而且很麻烦,仅仅是记录一下在开发过程中遇到的问题。

Logo

前往低代码交流专区

更多推荐