微信小程序实现本地图片压缩

最近在刚好遇到要压缩图片,网上随手搜了一下图片在线压缩,结果要么需要登录、要么要看广告,感觉很麻烦,于是乎,就在我的小程序“小白工具集”里撸了一个图片压缩的功能(写小程序纯属个人爱好)
图片大小必然遵循两个原则
1、相同格式下图片越清晰,文件越大
2、相同格式下图片尺寸越大,文件越大
所以我们压缩就只干两件事:可接受的范围内变的更模糊、变的更小

实现步骤

1、通过相册、相机或会话选择文件的api来拿到临时文件
2、识别设备类型,非ios设备直接使用微信官方的压缩api,然后over!
3、区分图片类型,JPG图片同样直接使用微信官方的压缩api,然后over!
4、计算压缩、裁切后的图片大小,将图片绘制到画布上,然后导出为JPG格式,最后同样是使用微信官方的压缩api,然后over!

but,坑来了,ios真机上高度或者宽度过大的图片画布在导出时抛canvasToTempFilePath:fail parse native buffer parameter error. native buffer exceed size limit异常,没办法只能继续打补丁:先导出为base64然后再生成临时文件,再进行压缩…无语了…

小程序API列表

下面列举可能会用到的一些API,大家可以根据自己的需求选择使用

  • wx.chooseMedia 选择媒体文件。
    设置mediaType:['image']sourceType:['album','camera'],从相册、相机读取文件,拿到临时文件地址

  • wx.chooseMessageFile 从会话选择聊天文件
    设置type: 'image'来过滤图片文件,可以很方便的从聊天会话或文件传输助手拿到文件

  • wx.getFileSystemManager().getFileInfo 获取文件信息
    根据临时文件路径拿到文件的大小

  • wx.getImageInfo 获取图片信息
    这里接口也支持下载网络图片,我们这里仅仅用它来根据临时文件路径获取图片的宽和高

  • wx.compressImage 图片压缩接口
    这个接口是微信提供的图片压缩API,可选压缩质量,很方便…但是吧,iOS端仅支持压缩 JPG格式图片😓,所以还得用其它方式来辅助完成压缩,大致思路是使用canvas画布,通过画布来完成图片的重绘,实现其它格式转JPG,进而实现继续使用wx.compressImage来压缩

  • wx.getDeviceInfo().system 获取设备系统信息
    用于识别设备

  • canvas 画布
    负责图片绘制、压缩

  • wx.canvasToTempFilePath 画布导出为临时文件

  • wx.base64ToArrayBuffer base64转buffer

  • wx.getFileSystemManager().writeFile 写文件

关键代码

从相册选择图片

wx.chooseMedia({
  count: 9,
  mediaType: ['image'],
  sizeType: ['original'],
  sourceType: ['album'],
  success: function (res) {
    const images = res.tempFiles.map(i => {
      console.log(i.tempFilePath, i.size);
    });
  },
  fail: function (err) {
    console.error('选择媒体文件失败:', err);
  }
})

从相机拍照

wx.chooseMedia({
  count: 1,
  mediaType: ['image'],
  sizeType: ['original'],
  sourceType: ['camera'],
  success: function (res) {
    const images = res.tempFiles.map(i => {
      console.log(i.tempFilePath, i.size);
    });
  },
  fail: function (err) {
    console.error('选择媒体文件失败:', err);
  }
})

从会话选择图片

wx.chooseMessageFile({
  count: 9,
  type: 'image',
  success: function (res) {
    const images = res.tempFiles.map(i => {
      console.log(i.path, i.size);
    });
  },
  fail: function (err) {
    console.error('选择媒体文件失败:', err);
  }
})

加载图片大小

const fs = wx.getFileSystemManager();
fs.getFileInfo({
  filePath: '文件路径',
  success: (res) => {
    console.log(res);
  },
  fail: (error) => {
    console.error(error);
  }
});

加载图片宽高

wx.getImageInfo({
  src: '',
  success: function (imageInfo) {
    console.log(imageInfo);
  },
  fail: function (err) {
    console.error('获取图片信息失败:', err);
  }
});

微信api直接压缩

wx.compressImage({
  src: '图片路径',
  quality: 80, //压缩质量
  compressedWidth: 900, //压缩后宽
  compressedHeight: 900, //压缩后高
  success(res) {
    console.log(res.tempFilePath);
  },
  fail: (err) => {
    console.error(err);
  }
})

canvas重绘压缩

const query = this.createSelectorQuery()
let dom = query.select('#canvasId') //画布id
dom.fields({ node: true, size: true })
  .exec((res: any) => {
    const canvas = res[0].node
    canvas.width = 900 //压缩后宽
    canvas.height = 900 //压缩后高
    const ctx = canvas.getContext('2d')
    let img = canvas.createImage();
    img.src = ''; //要压缩的图片路径
    img.onload = function () {
      // 将图片绘制到canvas
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
      //大于4096的先转base64,再写入文件
      if (canvas.width > 4096 || canvas.width > 4096) {
        //转成base64图片后的质量和类型
        const base64Data = canvas.toDataURL('image/jpeg', 0.8);
        const base64 = base64Data.replace(/^data:image\/\w+;base64,/, '');
        const buffer = wx.base64ToArrayBuffer(base64);
        const filePath = `${wx.env.USER_DATA_PATH}/test.jpg`;
        wx.getFileSystemManager().writeFile({
          filePath,
          data: buffer,
          encoding: 'binary',
          success() {
            console.log("写入成功", filePath);
          },
          fail: (err) => {
            console.error(err);
          }
        });
      } else {
        // 生成图片
        wx.canvasToTempFilePath({
          canvas,
          destWidth: 900, //压缩后宽
          destHeight: 900, //压缩后高
          fileType: 'jpg',
          quality: 0.8, //质量,可自定义
          success(res) {
            console.log(res.tempFilePath);
          },
          fail: (err) => {
            console.error(err);
          }
        })
      }
    }
  })

最后附上效果图欢迎大家微信小程序搜索“小白工具集”体验

效果图

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搬砖赚钱养家

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

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

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

打赏作者

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

抵扣说明:

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

余额充值