微信小程序实现照片裁剪

Serena ·
更新时间:2024-09-20
· 468 次阅读

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

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

组件代码

1.cut_photo.json

{   "component": true }

2.cut_photo.wxml

<view>   <canvas class="fyj_canvas" canvas-id="myCanvas" style="width:100%;height:{{canvasHeight}}px">     <movable-area class="fyj_movable_area text-center hidden" style="width:100%;height:{{canvasHeight}}px;">       <movable-view wx:if="{{src}}" style="width:{{cutWidth}}px;height:{{cutHeight}}px" class="fyj_movable_view"         x="{{x}}"         y="{{y}}"         direction="all"         bindchange="movableChange"       ></movable-view>       <image  class="fyj_photo" id="fyj_photo" src="{{src}}" mode="widthFix"></image>     </movable-area>   </canvas>   <view style="margin-top:20rpx;padding:0 20rpx;">     <button class="pull-left" type="warn" size="mini" bindtap="getPhoto">选择照片/拍照</button>     <button class="pull-right" type="primary" size="mini" bindtap="cut">裁剪</button>     <view class="clearfix"></view>   </view> </view>

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

<view> <!-- aspectRatio 剪裁图片的宽高比 -->   <cut-photo aspectRatio="0.5" bindgetTempFilePath="getCutsrc"></cut-photo>   <view wx:if="{{cut_src}}" class="fyj_cutDiv text-center">     <image style="width:{{cutWidth}}px;height:{{cutHeight}}px" class="fyj_cut_photo" src="{{cut_src}}" mode="widthFix"></image>   </view>   <view wx:if="{{cut_src}}"  class="fyj_footer text-center">     <button class="fyj_footerBtn fyj_sure" bindtap='sure'>确定</button>   </view> </view>

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的宽高。



照片 微信 小程序 程序 微信小程序

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章