小程序图片剪切

项目要求有个拍照后剪切功能,然而发现小程序他居然没有剪切的原生api
冷静,百度搜了下,发现有写好的demo
看起来好像也不是特别麻烦,要不自己写一个?
那就写吧
Three days later ........
 

着急用的话有我自己写好的demo, git地址  https://gitee.com/singlever/applet_demo

用法,在json文件中引入组件后(路径自己定好,这里只是我的路径)

  "usingComponents": {
    "img-shear": "./components/img_shear/index",
  },

在页面中加入下面代码   shear控制组件加载,剪切后的图片数据会传入 showimg方法中

<view wx:if="{{shear}}">
    <img-shear bind:imgdata="showimg" />
</view>

步入正题


1.通过  wx.chooseImage 拿到需要处理的图片

    wx.chooseImage({
      success: function(res){}
    })

2.通过 wx.getImageInfo 拿到图片的全部数据

    wx.chooseImage({
      success: function(res){
        wx.getImageInfo({
          src:res.tempFilePaths[0],
          success(data){
          }
        })
      }
    })


3.容器页面,这里我选用 scroll-view 组件来对选择好的图片进行滑动,内嵌 canvas 来绘制图片

  <scroll-view scroll-x="true" scroll-y="true">
    <canvas id="canvas" canvas-id="mycanvas"/>
  </scroll-view>

4.确定容器宽高,并且绘制图片,设置scroll-view的宽高决定切图视角的宽高,canvas的宽高为绘制图片的宽高,通过 wx.createCanvasContext 读取到被渲染的canvas,setData 把图片的数据和绑定好的canvas节点上传到data中,再通过节点绑定data中的数据进行渲染

  data: {
    ctx:'',
    cnavasimg:{},
  }, 
    const ctx =  wx.createCanvasContext('mycanvas',this)
    this.setData({ctx})
    let _this = this
    wx.chooseImage({
      success: function(res){
        wx.getImageInfo({
          src:res.tempFilePaths[0],
          success(data){
            _this.setData({
              cnavasimg:{...data,src:res.tempFilePaths[0]}})
            ctx.drawImage(res.tempFilePaths[0], 0, 0,data.width, data.height)
            ctx.draw()
          }
        })
      }
    })
  <scroll-view scroll-x="true" scroll-y="true" class="con">
    <canvas style="width:{{cnavasimg.width}}px;height:{{cnavasimg.height}}px" canvas-id="mycanvas" id="canvas" />
  </scroll-view>

这里初步的渲染已经完成


5.通过用户双指的距离来对图片进行缩放,并且及时渲染到节点中去,这里用到 bindtouchstart 和 bindtouchmove 来确定两指之间的位置

  <scroll-view scroll-x="true" scroll-y="true" bindtouchstart="touchstart" bindtouchmove="touchmove" class="con">

 

好累,接下来不放完整代码了,我就说说流程和思路吧


(1).两手指刚触碰屏幕时,触发 bindtouchstart 绑定的方法,在data中记录下两手指的 clientX 和 clientY,通过勾股定理计算出此时两指的距离
 

        let x = res.touches[0].clientX - res.touches[1].clientX
        let y = res.touches[0].clientY - res.touches[1].clientY
        x = x > 0 ? x : -x
        y = y > 0 ? y : -y
        // console.log('x',x,'y',y)
        let z = Math.sqrt(Math.pow(x,2)+Math.pow(y,2))
        return z

(2)手指滑动的时候,同样计算两指距离,给个if判定,两者的差 的正负来判断是否缩放  ,drawImage 函数是用来绘制图形的

    touchmove(res){
      if (res.touches.length === 1) {return}
      let bei = this.compute_z(res) - this.data.now_length
      if(bei > 0){
        this.drawImage(bei)
      }
      if(bei < -0){
        this.drawImage(bei)
      }
    },

(3)drawImage ,绘制图形,思路 首先 先用 ctx.clearRect() 来清屏,然后通过传入的参数 bei 的大小正负来对图片进行缩放,我这里的算法是

      let img = this.data.cnavasimg
      let width,height;
      let limit = 1000
      if(bei > 0){
        width = ((bei/limit)+1)*img.width
        height = ((bei/limit)+1)*img.height
      }else{
        bei = -bei
        width = (limit/(limit+bei))*img.width
        height = (limit/(limit+bei))*img.height
      }

(4)canvas容器的大小要随图片大小改变

this.setData({['cnavasimg.width']:width,['cnavasimg.height']:height})

(5)绘制图片

      ctx.drawImage(img.src, 0, 0,this.data.cnavasimg.width, this.data.cnavasimg.height)
      ctx.draw()

6.这里对于图片的放大缩小逻辑已经完了,现在是开始切图
使用 scroll-view 的 bindscroll 绑定的方法,及时传递图片所切位置的left和top
 

    location(e){
      this.data.view_left = e.detail.scrollLeft
      this.data.view_top = e.detail.scrollTop
    },

切图

    qie(){
      let w = 500*(this.data.w/750)
      let _this = this
      wx.canvasToTempFilePath({
        canvasId: 'mycanvas',
        height: w,
        width: w,
        x: _this.data.view_left,
        y: _this.data.view_top,
        success(res){
          _this.triggerEvent('imgdata',res.tempFilePath)
        }
      }, _this)
    },

通过点击按钮触发函数 qie 数据 ,w 是所切的图片宽高这里默认是 500rpx ,切图的api是   wx.canvasToTempFilePath()
再通过  this.triggerEvent 方法,将获得的图片数据传给调用页面。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值