uniapp 開發小程序壓縮圖片 - 新聞資(zī)訊 - 雲南小程序開發|雲南軟件開發|雲南網站(zhàn)建設-西山區知普網絡科技工作室

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不管是網站(zhàn),軟件還是小程序,都要直接或間接能為您産生價值,我們在追求其視覺表現的同時,更側重于功能的便捷,營銷的便利,運營的高效,讓網站(zhàn)成為營銷工具,讓軟件能切實提升企業(yè)内部管理水平和(hé)效率。優秀的程序為後期升級提供便捷的支持!

uniapp 開發小程序壓縮圖片

發表時間:2021-2-3

發布人:葵宇科技

浏覽次數:117

小程序壓縮圖片和(hé)普通(tōng) html 壓縮圖片思路(lù)一緻。

步驟為:

  1. 獲取圖片信息
  2. 獲取canvas 節點
  3. 創建圖片對象
  4. 壓縮圖片

詳細代碼

/**
 * 獲取圖片信息
 * @param {string} imgObj 圖片對象path
 * @param {function} fn 回調函數
 * @returns {ojbect} cbParams 
 * {
 *  height: 722,
 *  width: 1366,
 *  type: 'png',
 *  path: '',
 *  orientation: 'up',
 *  errMsg: ''
 * }
 */
function getImageObject (src, fn) {
  uni.getImageInfo({
    src: src,
    success (res) {
      fn(res)
    }
  })
}

/**
 * 壓縮圖片
 * @param {object} img 圖片
 * @param {function} fn 回調函數
 */
function compressImg (img, fn) {
  const selectorQuery = uni.createSelectorQuery()
  selectorQuery.select('#canvas')
    .fields({node: true, size: true})
    .exec(res => {
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      canvas.height = img.height
      canvas.width = img.width

      let seal = canvas.createImage();
      seal.src = http://www.wxapp-union.com/img.path;
      seal.onload = () => {
        ctx.drawImage(seal, 0, 0, img.width, img.height)
        const url = canvas.toDataURL('image/jpeg', .1)
        fn(url)
      }
    })
}

使用方法

getImageObject(list[0].file.path, img => {
  compressImg(img, res => {
    console.log(res);
  })
})

新發現

base64字符的長度就是文(wén)件尺寸 

/**
 * 返回圖片尺寸
 * @param {string} url base64 url
 * @param {functino} fn 返回圖片尺寸
 */
function getSize(url, fn) {
  let arr = url.split(',')[1],
    bstr = atob(arr),
    n = bstr.length;
  fn(n)
}

普通(tōng)壓縮圖片處理

這裡假設壓縮上傳的文(wén)件。

步驟為:

  1. 獲取 File 文(wén)件
  2. File && filereader.readAsDataURL(file) 生成 base64 編碼
  3. 創建 Image 對象 && Image.src = http://www.wxapp-union.com/base64 url
  4. 創建 canvas && ctx.drawImage() && canvas.toDataURL(type, encoderOptions)
  5. 生成 base64 url

詳細代碼

  function Compress(obj) {
    this.file = obj.file
    this.fileType = this.file.type // mime type
    this.filename = this.file.name // 文(wén)件名
    this.beforeSize = this.file.size
    this.factor = obj.factor // 壓縮比例(取值範圍:0-1)
  }

  /**
  * 生成 base64 url
  * @params { File } file 文(wén)件
  * @params { function } fn 回調函數
  * */
  function toDataurl(file, fn) {
    const filereader = new FileReader()
    filereader.readAsDataURL(file)
    
    filereader.onload = () => {
      const url = filereader.result
      if (url) {
        // ---------vvvvvvvv 測試句 vvvvvvvv---------
        addImg(url)
        // ---------^^^^^^^ 測試句 ^^^^^^^----------
        fn(url)
        console.info('before: ' + file.size)
      } else {
        console.error('filereader error');
      }
    }
  }

  /**
  * 創建 image 對象
  * @params { string } base64 url
  * @params { string } filename 文(wén)件名
  * @params { function } fn 回調函數
  * */
  function dataurl2File (url, filename, fn) {
    let type = url.split(',')[0].replace(/^.*:(.*);.*$/, '$1'), 
          arr = url.split(',')[1], 
          bstr = atob(arr), 
          n = bstr.length;
    let u8arr = new Uint8Array(n); 
  
    while(n --) {
      u8arr[n] = bstr.charCodeAt(n)
    }

    const file = new File([u8arr], filename, {type: type})
    fn(file)
  }

  /**
  * 創建 image 對象
  * @params { string } base64 編碼
  * @params { function } fn 回調函數
  * */
  function createImg(dataurl, fn) {
    const img = new Image()
    img.src = http://www.wxapp-union.com/dataurl
    img.onload = () => {
      fn(img)
    }
  }

  Compress.prototype = {
    /**
    * 文(wén)件生成 base64 url => 創建 image 對象
    * */
    init() {
      toDataurl(this.file, url => {
        createImg(url, img => {
          this.run(img)
        })
      })
    },
    /**
    * 創建 canvas 對象 => 壓縮并轉化為圖片
    * */
    run(img) {
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      canvas.width = img.width
      canvas.height = img.height
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

      // 此句為實現壓縮關(guān)鍵句
      this.newDataurl = canvas.toDataURL('image/jpeg', this.factor)
      // ---------vvvvvvvv 測試句 vvvvvvvv---------
      addImg(this.newDataurl)
      // ---------^^^^^^^ 測試句 ^^^^^^^----------

      dataurl2File(this.newDataurl, this.filename, (file) => {
        console.info('after: ' + file.size);

        if (this.beforeSize > file.size) {
          console.info('壓縮成功');
        } else {
          console.error('壓縮失敗');
        }
      })
    }
  }
  /**
  * 對比壓縮前後的兩個(gè)圖片
  * */
  function addImg (url) {
    const img = new Image()
    img.src = http://www.wxapp-union.com/url

    document.body.appendChild(img)
  }

使用方法

  /**
  * 獲取上傳文(wén)件,創建壓縮圖片實例,壓縮圖片
  * */
  function compressFile() {
    const dom = document.querySelector('[name=file]')

    dom.addEventListener('change', () => {
      const file = dom.files[0]
      const cp = new Compress({
        file: file,
        factor: 0.1
      })
      cp.init()
    })
  }

  window.onload = function () {
    compressFile()
  }

報錯處理

1、 小程序 canvas drawImage 報錯:

TypeError: Failed to execute 'drawImage' 報錯
解決辦法

let seal = canvas.createImage();
seal.src = http://www.wxapp-union.com/img.path;
seal.onload = () => {
  ctx.drawImage(seal, 0, 0, img.width, img.height)
  // 壓縮圖片
  const url = canvas.toDataURL('image/jpeg', .1)
}

??:壓縮圖片時要注意 canvas.toDataURL 的第一個(gè)參數是 image/jpeg 或 image/webp 時可(kě)以壓縮。

相關(guān)案例查看更多