微信小程序开发图片压缩解决办法

微信小程序开发过程中,有上传图片的需求,但是由于微信自带的压缩功能无法把图片压缩到指定大小,或者根据情况来压缩或者不压缩,那就就需要用到自己的压缩处理办法。

本我我已我的在线客服发送图片为例,讲解一下微信图片压缩的实现。

1 微信图片选择进行压缩的场景。

我的在线客服系统,支持发送图片,但是小程序中默认打开相册之后,往往图片比较大,而且由于手机的不同像素往往都比较高,图片就比较大,但是在线客服系统,往往不需要这么高质量图片,而且受限于socket的连接时间限制,上传时间就必须要快,所以我这里就需要对微信选择的图片进行压缩。

注意:由于微信上传和canvas的接口已经变更,网上有一些代码已经不符合现在新版微信canvas的接口要求了,所以这里代码是确定保证能够正常运行的代码。

uniapp小程序开发:

chooseImage() {
      let _this = this;
      _this.imguploading = true;
      wx.chooseImage({
        count: 1,
        sizeType: ["compressed"],
        success: (res) => {
          const tempFilePath = res.tempFilePaths[0];

          wx.getFileSystemManager().getFileInfo({
            filePath: tempFilePath,
            success: function (res) {
              let cW = res.width,
                cH = res.height,
                rat = 1.1;
              _this.cWidth = cW;
              _this.cHeight = cH;
            },
          });
          // wx.getFileInfo({
          //   filePath: tempFilePath,
          //   success: function (res) {
          //     let cW = res.width,
          //       cH = res.height,
          //       rat = 1.1;
          //     _this.cWidth = cW;
          //     _this.cHeight = cH;
          //   },
          // });
          getLessLimitSizeImage(
            "canvas",
            _this,
            tempFilePath,
            400,
            500,
            function (img) {
              console.log(img, "---");
              wx.uploadFile({
                // url: `${http_protocol}://${hostname}:${http_port}/im/image/upload.html?userid=${_this.config.userid}&appid=${_this.config.appid}&username=${_this.config.name}&orgi=${_this.config.orgi}`,
                url: `${http_protocol}://${hostname}/im/image/upload.html?userid=${_this.config.userid}&appid=${_this.config.appid}&username=${_this.config.name}&orgi=${_this.config.orgi}`,
                name: "imgFile",
                filePath: img,
                success: function (res) {
                  _this.imguploading = false;
                  //上传成功
                  // debugger;
                },
                fail: function (res) {
                  _this.imguploading = false;
                  _this.$u.func.showToast({ title: "发送图片失败,请重试" });
                  debugger;
                },
              });
            }
          );
        },
        fail: (res) => {
          _this.imguploading = false;
          // _this.$u.func.showToast({ title: "发送图片失败,请重试" });
        },
        complete: (res) => {
          _this.imguploading = false;
        },
      });
    },

如上代码
sizeType: ["compressed"]

这个地方是微信自带的压缩方式,但是并不满足我们的需求,所以需要配合我们的自定义函数和canvas实现。

wx.getFileSystemManager().getFileInfo() 这里是微信新版接口获取图片信息的接口。有好处也有缺点。后面会讲旧版wx.getFileInfo接口的优点。

2 通过自定义函数getLessLimitSizeImage实现对图片的压缩。

getLessLimitSizeImage函数参数。

  canvasId: 微信canvas 2.0的id值

  currentInstance: 这个很重要,这就是当前页面组件的实例,这个就是自定义函数内部用来使用wx.createSelector的api中in(this)的对象,不让我们是无法从过query方法去获取当前页面的canvas的。

  imagePath: 这个这就微信wx.chooseImage API返回的临时图片经验,也是通过这个图片我们实现再canvas上绘制截图的。

  limitSize = 100 这个是对小于100KB的图片不进行压缩限制。

  drawWidth: 这个就是我们要压缩到的目标宽度

  callBack: 这个就是我们压缩完成后重新拿到的图片回调函数。

3 接下来就是我们这个函数的封装

//*************** 图片压缩 ***********
// 判断图片大小是否满足需求
function imageSizeIsLessLimitSize(
  imagePath,
  limitSize,
  lessCallBack,
  moreCallBack
) {
  wx.getFileSystemManager().getFileInfo({
    filePath: imagePath,
    success(res) {
      console.log("压缩前图片大小:", res.size / 1024, "kb");
      if (res.size > 1024 * limitSize) {
        moreCallBack();
      } else {
        lessCallBack();
      }
    },
  });
}
/**
 * 获取画布图片
 */
// 利用cavas进行压缩 
function getCanvasImage(
  canvasId,
  currentInstance,
  imagePath,
  imageW,
  imageH,
  getImgsuccess
) {
  // const ctx = wx.createCanvasContext(canvasId);
  wx.createSelectorQuery()
    .in(currentInstance)
    .select("#" + canvasId)
    .node(({ node: canvas }) => {
      canvas.width = imageW;
      canvas.height = imageH;
      const ctx = canvas.getContext("2d");
      const bg = canvas.createImage();
      bg.src = imagePath;
      bg.onload = () => {
        ctx.save();
        ctx.translate(canvas.width / 2, canvas.height / 2);
        ctx.translate(-canvas.width / 2, -canvas.height / 2);
        ctx.drawImage(bg, 0, 0, imageW, imageH);
        ctx.restore();
        wx.canvasToTempFilePath({
          canvas,
          fileType: "jpg",
          quality: 1,
          success: (res) => {
            getImgsuccess(res.tempFilePath);
          },
        });
      };
    })
    .exec();
}

// 主调用方法

/**
 * 获取小于限制大小的Image
 */
function getLessLimitSizeImage(
  canvasId,
  currentInstance,
  imagePath,
  limitSize = 100,
  drawWidth,
  callBack
) {
  imageSizeIsLessLimitSize(
    imagePath,
    limitSize,
    (lessRes) => {
      callBack(imagePath);
    },
    (moreRes) => {
      wx.getImageInfo({
        src: imagePath,
        success: function (imageInfo) {
          var maxSide = Math.max(imageInfo.width, imageInfo.height);
          var windowW = drawWidth;
          var scale = 1;
          if (maxSide > windowW) {
            scale = windowW / maxSide;
          }
          var imageW = Math.trunc(imageInfo.width * scale);
          var imageH = Math.trunc(imageInfo.height * scale);
          getCanvasImage(
            canvasId,
            currentInstance,
            imagePath,
            imageW,
            imageH,
            (pressImgPath) => {
              console.log("callback", pressImgPath);
              getLessLimitSizeImage(
                canvasId,
                currentInstance,
                pressImgPath,
                limitSize,
                drawWidth * 0.95,
                callBack
              );
            }
          );
        },
      });
    }
  );
}
function getBase64(img) {
  return new Promise(function (resolve, reject) {
    const FSM = wx.getFileSystemManager();
    FSM.readFile({
      filePath: img,
      encoding: "base64",
      success(data) {
        resolve(data);
      },
    });
  });
}

export {
  getLessLimitSizeImage,
  imageSizeIsLessLimitSize,
  getCanvasImage,
  getBase64,
};

以上就是对自定义函数的分装,本文结合了最新的微信api实现。

createSelectorQuery这个微信提供的查找页面dom的方法,这里如果要查找canvas的话,按照目前新版微信api的话,要确保再in(this)的情况下才会找到,并且canvas的写法上也有所不同。

 <canvas
      class="canvas"
      id="canvas"
      type="2d"
      :style="{
        width: cWidth + 'px',
        height: cHeight + 'px',
        visibility: 'hidden',
        position: 'absolute',
        'z-index': '-1',
        left: '-10000rpx',
        top: '-10000rpx',
      }"
    ></canvas>

这就是本人目前再小程序中实现的图片压缩的方法。欢迎指正。

如上图是一张大图片

 

经过压缩

目前从整体情况来看,非常符合我们的实际需求。 

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
图片压缩微信小程序中是一个很常见的需求,下面是一个简单的图片压缩的全过程: 1. 用户选择图片并上传到服务器,服务器返回图片的 URL。 2. 在小程序中,通过 wx.getImageInfo() 方法获取图片信息,包括图片的宽、高等属性。 3. 使用 canvas 绘制图片,并调用 canvas.toDataURL() 方法将图片转换成 base64 编码的字符串。 4. 将 base64 字符串发送到服务器,服务器将其转换成图片并进行压缩处理。 5. 服务器将压缩后的图片返回给小程序,并将其显示在页面上。 下面是一个代码示例: ``` // 选择图片并上传到服务器 wx.chooseImage({ success: function(res) { var tempFilePaths = res.tempFilePaths; wx.uploadFile({ url: 'your server url', filePath: tempFilePaths[0], name: 'file', success: function(res){ var imageUrl = res.data; // 服务器返回的图片 URL // 获取图片信息 wx.getImageInfo({ src: imageUrl, success: function(res){ var canvasWidth = res.width, // 图片宽度 canvasHeight = res.height; // 图片高度 // 绘制图片到 canvas var context = wx.createCanvasContext('canvas'); context.drawImage(imageUrl, 0, 0, canvasWidth, canvasHeight); context.draw(false, function(){ // 将 canvas 图片转换成 base64 编码的字符串 wx.canvasToTempFilePath({ canvasId: 'canvas', success: function(res){ var base64Data = res.tempFilePath.replace(/^data:image\/\w+;base64,/, ''); // 发送 base64 字符串到服务器进行压缩 wx.request({ url: 'your server url', data: { imageData: base64Data }, method: 'POST', success: function(res){ var compressedImageUrl = res.data; // 压缩后的图片 URL // 在页面上显示压缩后的图片 wx.previewImage({ urls: [compressedImageUrl], }); } }); } }); }); } }); } }) } }); ``` 注意,以上代码仅供参考,具体实现方式可能因应用场景不同而有所差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaolongyu3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值