微信小程序开发 图片压缩功能

在微信小程序的开发过程中,为了防止用户在上传图片时出现过大文件的情况,造成后台的加载负担,我们通常会在前台加上大小的限制或在上传时就对图片进行压缩

微信小程序官方为我们提供了一个API:wx.compressImage,

但仔细查看后我们发现,这个API在iOS端仅支持压缩JPG格式的图片,显然不太符合我们的需求。

经过一番查阅后,决定采用canvas绘图的方式来对图片重新进行绘制,从而达到压缩的效果。

下面是具体的实现流程:

<canvas id="myCanvas" class="canvas-case" type="2d" style="border: 1px solid; width: 300px; height: 150px;" />

首先,创建一份画布,如果不需要图片的显示的话可以直接移出可视范围

const query = this.createSelectorQuery()
let dom = query.select('#myCanvas') // 获取 canvas 元素

核心代码:

async contraction(file, canvasId, config = {
    maxWidth: 1024,
    maxHeight: 768
  }) {
    try {
      let ctxInfo = await new Promise((resolve, reject) => {
        // 获取图片原始宽高
        let width = file.width
        let height = file.height

        // 计算图片当前大小和目标大小的比例:目标大小 / 图片当前大小
        // 根据比例调整图片的尺寸:
        // 新宽度 = 原始宽度 * √(目标大小 / 图片当前大小) 
        // 新高度 = 原始高度 * √(目标大小 / 图片当前大小)
        // 宽高同比例调整
        // 宽度 > 最大限宽 -> 重置尺寸
        if (width > config.maxWidth) {
          const ratio = config.maxWidth / width
          width = config.maxWidth
          height = height * ratio
        }
        // 高度 > 最大限高度 -> 重置尺寸
        if (height > config.maxHeight) {
          const ratio = config.maxHeight / height
          width = width * ratio
          height = config.maxHeight
        }

        // 获取canvas元素
        const query = wx.createSelectorQuery()
        let dom = query.select(`#${canvasId}`)
        dom.fields({
            node: true,
            size: true
          })
          .exec((res) => {
            // Canvas 对象
            const canvas = res[0].node
            // 渲染上下文
            const ctx = canvas.getContext('2d')

            // 根据设备像素比处理尺寸 = 大小 * 设备像素
            const dpr = wx.getSystemInfoSync().pixelRatio
            canvas.width = width * dpr
            canvas.height = height * dpr
            ctx.scale(dpr, dpr)

            //创建img对象
            let img = canvas.createImage();
            img.src = file.path; // 给图片添加路径
            //图片加载完毕
            img.onload = function () {
              // 将图片绘制到 canvas
              ctx.drawImage(img, 0, 0, width, height)
              // 生成图片
              wx.canvasToTempFilePath({
                canvas,
                x: 0,
                y: 0,
                destWidth: width,
                destHeight: height,
                success(res) {
                  resolve(res); // 生成临时文件路径
                }
              })
            }
          })
      })
      return ctxInfo
    } catch (err) {
      console.log(err);
    }
  },

顺带再加一个解析上传图片的方法,方便我们进行转换

//获取图片信息
  async getImgInfo(tempFilePath) {
    try {
      let image = await new Promise((resolve, reject) => {
        wx.getImageInfo({
          src: tempFilePath,
          success(res) {
            let imgInfo = {
              type: res.type,
              height: res.height,
              width: res.width,
              path: res.path
            }
            resolve(imgInfo)
          },
          fail(err) {
            reject(err)
          }
        })
      })
      return image
    } catch (err) {
      console.log(err);
    }
  },

希望能为你带来帮助

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值