微信小程序壓縮圖片

最近在剛好遇到要壓縮圖片,網(wǎng)上隨手搜了一下圖片在線(xiàn)壓縮,結(jié)果要么需要登錄、要么要看廣告,感覺(jué)很麻煩,于是乎,就在我的小程序“小白工具集”里擼了一個(gè)圖片壓縮的功能(寫(xiě)小程序純屬個(gè)人愛(ài)好)
圖片大小必然遵循兩個(gè)原則
1、相同格式下圖片越清晰,文件越大
2、相同格式下圖片尺寸越大,文件越大
所以我們壓縮就只干兩件事:可接受的范圍內(nèi)變的更模糊、變的更小

實(shí)現(xiàn)步驟

1、通過(guò)相冊(cè)、相機(jī)或會(huì)話(huà)選擇文件的api來(lái)拿到臨時(shí)文件
2、識(shí)別設(shè)備類(lèi)型,非ios設(shè)備直接使用微信官方的壓縮api,然后over!
3、區(qū)分圖片類(lèi)型,JPG圖片同樣直接使用微信官方的壓縮api,然后over!
4、計(jì)算壓縮、裁切后的圖片大小,將圖片繪制到畫(huà)布上,然后導(dǎo)出為JPG格式,最后同樣是使用微信官方的壓縮api,然后over!

but,坑來(lái)了,ios真機(jī)上高度或者寬度過(guò)大的圖片畫(huà)布在導(dǎo)出時(shí)拋canvasToTempFilePath:fail parse native buffer parameter error. native buffer exceed size limit異常,沒(méi)辦法只能繼續(xù)打補(bǔ)?。合葘?dǎo)出為base64然后再生成臨時(shí)文件,再進(jìn)行壓縮...無(wú)語(yǔ)了...

小程序API列表

下面列舉可能會(huì)用到的一些API,大家可以根據(jù)自己的需求選擇使用

  • wx.chooseMedia 選擇媒體文件。
    設(shè)置mediaType:['image']sourceType:['album','camera'],從相冊(cè)、相機(jī)讀取文件,拿到臨時(shí)文件地址

  • wx.chooseMessageFile 從會(huì)話(huà)選擇聊天文件
    設(shè)置type: 'image'來(lái)過(guò)濾圖片文件,可以很方便的從聊天會(huì)話(huà)或文件傳輸助手拿到文件

  • wx.getFileSystemManager().getFileInfo 獲取文件信息
    根據(jù)臨時(shí)文件路徑拿到文件的大小

  • wx.getImageInfo 獲取圖片信息
    這里接口也支持下載網(wǎng)絡(luò)圖片,我們這里僅僅用它來(lái)根據(jù)臨時(shí)文件路徑獲取圖片的寬和高

  • wx.compressImage 圖片壓縮接口
    這個(gè)接口是微信提供的圖片壓縮API,可選壓縮質(zhì)量,很方便...但是吧,iOS端僅支持壓縮 JPG格式圖片??,所以還得用其它方式來(lái)輔助完成壓縮,大致思路是使用canvas畫(huà)布,通過(guò)畫(huà)布來(lái)完成圖片的重繪,實(shí)現(xiàn)其它格式轉(zhuǎn)JPG,進(jìn)而實(shí)現(xiàn)繼續(xù)使用wx.compressImage來(lái)壓縮

  • wx.getDeviceInfo().system 獲取設(shè)備系統(tǒng)信息
    用于識(shí)別設(shè)備

  • canvas 畫(huà)布
    負(fù)責(zé)圖片繪制、壓縮

  • wx.canvasToTempFilePath 畫(huà)布導(dǎo)出為臨時(shí)文件

  • wx.base64ToArrayBuffer base64轉(zhuǎn)buffer

  • wx.getFileSystemManager().writeFile 寫(xiě)文件

關(guān)鍵代碼

從相冊(cè)選擇圖片

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);
  }
})

從相機(jī)拍照

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);
  }
})

從會(huì)話(huà)選擇圖片

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, //壓縮質(zhì)量
  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') //畫(huà)布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的先轉(zhuǎn)base64,再寫(xiě)入文件
      if (canvas.width > 4096 || canvas.width > 4096) {
        //轉(zhuǎn)成base64圖片后的質(zhì)量和類(lèi)型
        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("寫(xiě)入成功", filePath);
          },
          fail: (err) => {
            console.error(err);
          }
        });
      } else {
        // 生成圖片
        wx.canvasToTempFilePath({
          canvas,
          destWidth: 900, //壓縮后寬
          destHeight: 900, //壓縮后高
          fileType: 'jpg',
          quality: 0.8, //質(zhì)量,可自定義
          success(res) {
            console.log(res.tempFilePath);
          },
          fail: (err) => {
            console.error(err);
          }
        })
      }
    }
  })

最后,給大家看下成品效果圖

效果圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容