微信小程序 实现上传图片前裁剪功能

前言

        技术支持: wx-cropper 裁剪

        总体思路是:安装完wx-cropper之后就它当成组件使用。在使用页面的地方引入组件就行。上传图片的逻辑不变,在 通过wx.chooseMedia() Api 拿到图片之后传递给子组件,子组件在拿到图片进行裁剪处理等操作之后,在把图片传递给父组件,父组件在拿到处理之后的图片,在进行自己之后的逻辑操作。简单来说就是------父组件上传图片-->子组件拿到图片进行处理-->处理的图片给父组件-->自己的逻辑操作

一. 引入wx-cropper

npm i @dw/wx-cropper

安装wx-cropper之后构建npm

二. 在需要使用的页面上引入

{
  "usingComponents": {
    "my-cropper": "@dw/wx-cropper"
  }
}

 三. 示例

        1. wxml代码

<button catchtap="handleuploadimg">上传图片</button>

<block wx:for="{{ fileList }}" wx:key="*this">
  <image src="{{ item }}" mode=""/>
</block>

<view class="layers" wx:if="{{cjtp}}">
    <my-cropper bind:close="hideCut" cutRatio="{{cutRatio}}" imageSrc="{{imageSrc}}" />
</view>

        2. wxss样式 

                这个是需要把裁剪功能组件覆盖到当前页面上

/* pages/upload/upload.wxss */
.layers{
  width: 100vw;
  height: 100vh;
  background-color: #00000080;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10000000;
}

 

        3. js代码

                当选择完图片时,显示裁剪功能,以及把上传的图片传给组件。当用户裁剪完图片之后,会通过组件getImageInfo方法处理图片之后,在通过子组件向父组件传值的方法,把裁剪处理完之后图片传递给父组件 _this.triggerEvent('close', img);

// pages/upload/upload.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    fileList: [], //上传图片集合
    base64List: [], //base64集合
    delFileArr:[],  //删除的附件集合
    imgWidthslot: 0,
    imgHeightslot: 0,
    //裁剪信息
    cjtp: false,     //裁剪信息 这个控制裁剪功能的现实和隐藏
    cutRatio:0.75,  //裁剪比例
    imageSrc:'',    //个人图片
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },
  // 上传图片
  handleuploadimg() {
    wx.chooseMedia({
      count: 1,
      mediaType: ['image'],
      sourceType: ['camera', 'album'],
      success: (res) => {
        // this.setData({
        //   fileList: res.tempFiles
        // })
        var tempFilePaths = res.tempFiles;
        for (let i in tempFilePaths) {
          let imagePath = tempFilePaths[i].tempFilePath; //原图的路径
          let size = tempFilePaths[i].size;      //原图大小
            //this.setData({
             // imageSrc:imagePath,
              //cjtp:true,
            //})
            //判断是否需要压缩
           if(size > this.data.size){
              this.setCanvasLoad(imagePath);
           }else{
            this.setData({
              imageSrc:imagePath,
              cjtp:true,
            })
          }
          
        }
      }
    })
  },
// 压缩图片
setCanvasLoad(obj){
    let imagePath = obj; //原图的路径
      const ctx = wx.createCanvasContext('myfirstCanvasSlot',this);
      let that = this;
      wx.showLoading({
        title: '图片压缩中...',
        mask: true
      }) //不需要你可以删掉
      // console.log(imagePath,'原图的路径')
      wx.getImageInfo({
        src:imagePath,
        success:(res)=>{
          // console.log(res,'获取图片的属性')
          // 图片原始尺寸
          let originWidth = res.width;
          let originHeight = res.height;
          // 最大尺寸限制,可通过设置宽高来实现图片压缩程度
          let maxWidth = 1920,
              maxHeight = 800;
          // 目标尺寸
          let targetWidth = originWidth,
              targetHeight = originHeight;
          // 图片尺寸超过200x150的限制
          if(originWidth > maxWidth || originHeight > maxHeight) {
              if(originWidth / originHeight > maxWidth / maxHeight) {
                  // 更宽,按照宽度限定尺寸
                  targetWidth = maxWidth;
                  targetHeight = Math.round(maxWidth * (originHeight / originWidth));
              } else {
                  targetHeight = maxHeight;
                  targetWidth = Math.round(maxHeight * (originWidth / originHeight));
              }
          }
          // canvas对图片进行缩放
          this.setData({
              imgWidthslot: targetWidth,
              imgHeightslot: targetHeight
          })

          // 压缩图片(绘制图像到画布)
          ctx.drawImage(imagePath,0,0,targetWidth,targetHeight);
          console.log(this.data.imgWidth)

          ctx.draw(false, ()=>{
            setTimeout(()=>{
              // canvas导出为图片路径
              wx.canvasToTempFilePath({
                canvasId: 'myfirstCanvasSlot',
                fileType: 'png', //支持jpg或png
                quality: 0.92, //图片质量
                success:(res1)=> {
                    wx.hideLoading();
                    // console.log(targetWidth,targetHeight,'targetHeight')
                    let compressedPath = res1.tempFilePath;
                    //将图片转化为base64
                    this.setData({
                      imageSrc:compressedPath,
                      cjtp:true,
                    })
                },
                fail:(res1)=>{
                  // console.log('图片压缩失败',res)
                  wx.hideLoading()
                  wx.showModal({
                    content: '图片压缩失败',
                    showCancel:false
                  })
                }
              },that)
            },200)
             
          })
        },
        fail: (res) => {
          wx.hideLoading()
          // console.log(res,'获取图片的属性失败');
          wx.showModal({
            content: '图片压缩失败',
            showCancel:false
          })
        }
      })
  },
  
  //关闭裁剪
  hideCut(e){
    let obj = e.detail;
    let fileList = this.data.fileList;
    let base64List = this.data.base64List;
    //是否已经截取
    if(obj){
      console.log('------obj', obj)
      wx.showLoading({
        title: '裁剪中',
      })
      fileList = [ obj.path ]
      wx.getFileSystemManager().readFile({
        filePath: obj.path,
        encoding: "base64",
        success: (res) => {
          
          wx.hideLoading(); //不需要你可以删掉
          base64List = [res.data]
          this.setData({
            base64List: base64List,
            fileList: fileList,
          })

          console.log('-----res-----', this.data.base64List, this.data.fileList)
        },
        fail: (res) => {

          wx.hideLoading(); //不需要你可以删掉
          wx.showModal({
            content: '图片裁剪失败',
            showCancel:false
          })
        }
      })
    }
    this.setData({
      cjtp:false,
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

父组件会通过hideCut方法 来拿到子组件传递过来的图片,然后在回显到页面上。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值