微信小程序实现照片裁剪

发布时间:2023-10-29 18:30

本文实例为大家分享了微信小程序实现照片裁剪的具体代码,供大家参考,具体内容如下

前段时间用小程序的canvas、movable-area、movable-view封装了一个按比例裁剪照片的组件,无需引用任何插件。废话不多说,直接贴代码:

组件代码

1.cut_photo.json

{
  \"component\": true
}

2.cut_photo.wxml


  
    
      
      
    
  
  
    
    
    
  

3.cut_photo.js

const app = getApp()
Component({
  options: {
    //multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  properties: {
    // 这里定义了innerText属性,属性值可以在组件使用时指定
    //宽高比
    aspectRatio: {
      type: Number,
      value: 5/7, 
    }
  },
  data: {
    screenWidth: wx.getSystemInfoSync().windowWidth,
    canvasHeight: 300,
    x: 0,
    y: 0,
    src: \'\',
    cut_src: \'\',
    cutWidth: 0,
    cutHeight: 0
  },
  attached: function () {
    
  },
  methods: {
    // 这里是一个自定义方法
    //选择照片
    getPhoto: function () {
      const $this = this;
      const ctx = wx.createCanvasContext(\'myCanvas\',this)
      var obj = wx.createSelectorQuery();
      wx.chooseImage({
        count: 1,
        sizeType: [\'original\', \'compressed\'],
        sourceType: [\'album\', \'camera\'],
        success(res) {
          //清空之前的剪切图
          $this.triggerEvent(\'getTempFilePath\', { cut_src: \'\', cutWidth: $this.data.cutWidth, cutHeight: $this.data.cutHeight })
          // tempFilePath可以作为img标签的src属性显示图片
          const tempFilePaths = res.tempFilePaths[0];
          $this.setData({
            src: tempFilePaths,
            cut_src: \'\',
          });
          setTimeout(function () {
            wx.createSelectorQuery().in($this).select(\'#fyj_photo\').boundingClientRect(function (rect) {
              console.log(rect);
              console.log(rect.height);
              $this.setData({
                canvasHeight: rect.height
              })
              ctx.drawImage(tempFilePaths, 0, 0, $this.data.screenWidth, $this.data.canvasHeight)
              ctx.draw();
              $this.setCut();
              //确保不同大小的图片,切图不会变形
              $this.setData({
                x: 0,
                y: 0
              });
            }).exec()
          }, 100)
          

        }
      })
        
    },
    //获取图片高度
    // getHeight:function(){
    //   const query = wx.createSelectorQuery().in(this)
    //   query.selectAll(\'#fyj_photo\').boundingClientRect()
    //   query.exec(function (rect) {
    //     console.log(rect);
    //     console.log(rect[0].height);
    //     $this.setData({
    //       canvasHeight: rect[0].height
    //     })
    //     ctx.drawImage(tempFilePaths[0], 0, 0, $this.data.screenWidth, $this.data.canvasHeight)
    //     ctx.draw();
    //     $this.setCut();
    //   })
    // },
    //裁剪框移动事件
    movableChange: function (e) {
      console.log(e.detail);
      this.setData({
        x: e.detail.x,
        y: e.detail.y
      })
    },
    //截图
    cut: function () {
      const $this = this;
      console.log($this.data.cutHeight);
      wx.canvasToTempFilePath({
        x: $this.data.x,
        y: $this.data.y,
        width: $this.data.cutWidth,
        height: $this.data.cutHeight,
        destWidth: $this.data.cutWidth,
        destHeight: $this.data.cutHeight,
        canvasId: \'myCanvas\',
        success(res) {
          console.log(res.tempFilePath);
          $this.setData({
            cut_src: res.tempFilePath
          })
          $this.triggerEvent(\'getTempFilePath\', { cut_src: $this.data.cut_src, cutWidth: $this.data.cutWidth, cutHeight: $this.data.cutHeight})
        }
      },this)
    },
    //动态设置裁剪框大小,确定高度不得超过canvas的高度
    setCut: function () {
      const $this = this;
      this.setData({
        cutWidth: wx.getSystemInfoSync().windowWidth * 0.8,
        cutHeight: wx.getSystemInfoSync().windowWidth * 0.8/this.data.aspectRatio
      })
      if (this.data.cutHeight - 4 > this.data.canvasHeight) {
        console.log($this.data.cutHeight);
        console.log($this.data.canvasHeight);
        this.setData({
          cutHeight: this.data.canvasHeight - 4,
          cutWidth: (this.data.canvasHeight - 4)*this.data.aspectRatio
        })
      } else {
        this.setData({
          cutWidth: wx.getSystemInfoSync().windowWidth * 0.8,
          cutHeight: wx.getSystemInfoSync().windowWidth * 0.8/this.data.aspectRatio
        })
      }
      console.log($this.data.cutWidth);
      console.log($this.data.cutHeight);
    },
  }
})

4.cut_photo.wxss

.fyj_movable_area{width:100%;height:auto;position: relative;background:rgba(0,0,0,0.3)}
.fyj_movable_view{border:2px dashed #fff}
.fyj_photo{width:100%;}
.fyj_footer{margin-top:20rpx 0;}
.fyj_footerBtn{width:100%;display: inline-block;color:#fff;border-radius: 0;font-size:32rpx;}
.fyj_sure{background: #fc6b47;}
.pull-left{float:left;}
.pull-right{float:right}
.clearfix{clear:both}
.text-center{text-align: center}

引用页代码

1.page.json

{
  \"navigationBarTitleText\": \"选择照片\",
  \"usingComponents\": {
    \"cut-photo\": \"/pages/cut_photo/cut_photo\"
  }
}

2.page.wxml



  
  
    
  
  
    
  

3.page.js

const app = getApp()
Page({

  /**
   * 页面的初始数据
   */
  data: {
    cut_src:\'\',
    cutWidth:0,
    cutHeight:0,
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
   
  },
  getCutsrc:function(e){
    console.log(e);
    this.setData({
      cut_src: e.detail.cut_src,
      cutWidth: e.detail.cutWidth,
      cutHeight: e.detail.cutHeight

    })
  }
})

4.page.wxss

.fyj_footer{margin-top:20rpx 0;}
.fyj_footerBtn{width:100%;display: inline-block;color:#fff;border-radius: 0;font-size:32rpx;}
.fyj_sure{background: #fc6b47;}
.fyj_cutDiv{margin:20rpx 0;}

大概思路

将canvas跟movable-area重合,通过movable-view来确定裁剪区域。为了确保图片加载不变形,选择完图片后,需要动态设置canvas、movable-area的高度及movable-view的宽高。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号