微信小程序圖片裁剪工具 wx-cropper優化

wx-cropper源碼地址,感謝做者分享源碼。引用部分不用改動。優化部分我將詳細講解。
https://github.com/we-plugin/we-cropper
複製代碼

優化

  1. 獲取頁面高度,動態改變canvas高度時,應在onload回調函數中獲取,否則會出現bug,獲取的是上一頁的高度。
onLoad(option) {
    let device = wx.getSystemInfoSync()
    let height = device.windowHeight - 50;
    this.setData({
      ["cropperOpt.height"]: height,
      ["cropperOpt.cut.y"]: (height - 300) / 2,
    })
 }   
複製代碼
  1. 圖片若是模糊,是因爲手機像素比的問題,具體詳見https://github.com/we-plugin/we-cropper/wiki/FAQ。
// 全部參數乘設備像素比
      imgLeft = imgLeft * devicePixelRatio
      imgTop = imgTop * devicePixelRatio
      scaleWidth = scaleWidth * devicePixelRatio
      scaleHeight = scaleHeight * devicePixelRatio
      x = x * devicePixelRatio
      y = y * devicePixelRatio
      width = width * devicePixelRatio
      height = height * devicePixelRatio
複製代碼
  1. 裁切後圖片體積太大,解決該問題須要wx自帶api進行質量壓縮
wx.canvasToTempFilePath({
          canvasId: 'hideCanvas',
          x,
          y,
          width,
          height,
          destWidth: _that.data.uploadWidth,
          destHeight: _that.data.uploadHeight,
          fileType:'jpg',	//必須是jpg格式,png會使quality失效
          quality,	//圖片質量,參數為從零到一,0.7比較合適,壓縮完差很少100KB左右。
          success(res) {
            const tmpPath = res.tempFilePath;
            _that.afterGetPath(tmpPath)
          },
          fail(e) {
            console.log(e)
          }
        })
複製代碼
  1. 裁剪後會自動調用上一頁面的afterCuttingImg函數,參數為圖片的臨時路徑

項目源代碼

import WeCropper from './we-cropper/we-cropper.js'
const App = getApp();

const device = wx.getSystemInfoSync()
const width = device.windowWidth
const pixelRatio = device.pixelRatio
Page({
  data: {
    cropperOpt: {
      id: 'cropper',
      width,
      // height,
      pixelRatio,
      scale: 2.5,
      zoom: 8,
      cut: {
        x: (width - 300) / 2,
        // y: (height - 300) / 2,
        width: 300,
        height: 300
      }
    },
  },
  touchStart(e) {
    this.wecropper.touchStart({
      touches: e.touches.filter(i => i.x !== undefined)
    })
  },
  touchMove(e) {
    this.wecropper.touchMove({
      touches: e.touches.filter(i => i.x !== undefined)
    })
  },
  touchEnd(e) {
    this.wecropper.touchEnd()
  },

  uploadTap() {
    const self = this

    wx.chooseImage({
      count: 1, // 默認9
      sizeType: ['original', 'compressed'], // 能夠指定是原圖仍是壓縮圖,默認兩者都有
      sourceType: ['album', 'camera'], // 能夠指定來源是相冊仍是相機,默認兩者都有
      success(res) {
        const src = res.tempFilePaths[0]
        //  獲取裁剪圖片資源後,給data添加src屬性及其值

        self.wecropper.pushOrign(src)
      }
    })
  },

  //裁剪
  btnHandle() {
    //高清裁剪
    let quality = 0.7;
    if (this.data.quality) {
      quality = 1;
    }
    // if (this.data.quality) {
      let _that = this;
      // 點擊了裁剪按鈕
      let devicePixelRatio = this.data.cropperOpt.pixelRatio
      let { imgLeft, imgTop, scaleWidth, scaleHeight } = this.wecropper // 獲取圖片在原畫布座標位置及寬高
      let { x, y, width, height } = this.wecropper.cut // 獲取裁剪框位置及大小
      // 全部參數乘設備像素比
      imgLeft = imgLeft * devicePixelRatio
      imgTop = imgTop * devicePixelRatio
      scaleWidth = scaleWidth * devicePixelRatio
      scaleHeight = scaleHeight * devicePixelRatio
      x = x * devicePixelRatio
      y = y * devicePixelRatio
      width = width * devicePixelRatio
      height = height * devicePixelRatio

      const targetCtx = wx.createCanvasContext('hideCanvas') // 這裏是目標canvas畫布的id值

      targetCtx.drawImage(this.data.cropperOpt.src, imgLeft, imgTop, scaleWidth, scaleHeight) // tmp表明被裁剪圖片的臨時路徑

      targetCtx.draw(false, function (e) {
        wx.canvasToTempFilePath({
          canvasId: 'hideCanvas',
          x,
          y,
          width,
          height,
          destWidth: _that.data.uploadWidth,
          destHeight: _that.data.uploadHeight,
          fileType:'jpg',
          quality,
          success(res) {
            const tmpPath = res.tempFilePath;
            _that.afterGetPath(tmpPath)
          },
          fail(e) {
            console.log(e)
          }
        })
      })
    // } else {
    //   this.wecropper.getCropperImage((avatar) => {
    //     this.afterGetPath(avatar)
    //   })
    // }
  },
  afterGetPath(avatar) {
    if (avatar) {
      //  獲取到裁剪後的圖片
      var pages = getCurrentPages();
      if (pages.length > 1) {
        //上一個頁面實例對象
        var prePage = pages[pages.length - 2];
        //關鍵在這裏
        try {
          prePage.afterCuttingImg(avatar)
        } catch (e) {
          console.warn("please setting afterCuttingImg function to receive img url");
        }
        wx.navigateBack();
      }

    } else {
      console.log('獲取圖片失敗,請稍後重試')
    }
  },
  onLoad(option) {
    let device = wx.getSystemInfoSync()
    let height = device.windowHeight - 50;
    this.setData({
      ["cropperOpt.height"]: height,
      ["cropperOpt.cut.y"]: (height - 300) / 2,
    })

    const { cropperOpt } = this.data
    
    //裁圖質量
    if (option.quality) {
      this.setData({
        quality: true
      })
    }
    this.setData({
      uploadWidth:option.width,
      uploadHeight:option.height
    })

    if (option.src) {
      cropperOpt.src = option.src
      new WeCropper(cropperOpt)
        .on('ready', (ctx) => {
          // console.log(`wecropper is ready for work!`)
        })
        .on('beforeImageLoad', (ctx) => {
          // console.log(`before picture loaded, i can do something`)
          // console.log(`current canvas context:`, ctx)
          wx.showToast({
            title: '上傳中',
            icon: 'loading',
            duration: 20000
          })
        })
        .on('imageLoad', (ctx) => {
          // console.log(`picture loaded`)
          // console.log(`current canvas context:`, ctx)
          wx.hideToast()
        })
        .on('beforeDraw', (ctx, instance) => {
          // console.log(`before canvas draw,i can do something`)
          // console.log(`current canvas context:`, ctx)
        })
        .updateCanvas()
    }
  }
})

複製代碼
相關文章
相關標籤/搜索