微信小程序简单的canvas裁剪图片功能详解


Posted in Javascript onJuly 12, 2019

小程序miniso的一个发布内容截图功能,话不多,先上代码

wxml文件:

<view class="cut-1-1 t-c {{cutSelect == 1? 'cut-select':''}}" data-cut="1" bindtap="selectCutType">1:1</view>
<view class="cut-3-4 t-c {{cutSelect == 2? 'cut-select':''}}" data-cut="2" bindtap="selectCutType">3:4</view>
<block wx:for="{{imgList}}" wx:key="{{index}}" >
  <swiper-item>
  <scroll-view scroll-top="{{topNum}}" scroll-y class="imgFile {{cutSelect == 1?'view-1-1':'view-3-4'}}" bindscroll="endTou">
   <image src='{{item}}' mode="widthFix"></image>
  </scroll-view >
  </swiper-item>
</block>
<canvas wx:for="{{imgList}}" wx:for-index="i" canvas-id="myCanvas_{{i}}" style="width: {{width[i]?width[i]*2:750}}rpx; height: {{height[i]?height[i]*2:750}}rpx;"></canvas>

这里是对多张图片进行统一处理,用户选了哪种截图比例,所有图片用统一规格裁剪。

因为简单,不提供缩放和左右移动,所以只能裁剪竖长图,不支持横长图裁剪。

topNum用于scroll-view的reset处理

wxss文件

.view-1-1 {
 width: 750rpx;
 height: 750rpx;
 overflow: hidden;
}

.view-3-4 {
 width: 750rpx;
 height: 750rpx;
 padding: 0 94rpx;
 box-sizing: border-box;
 overflow: hidden;
}

canvas {
 position: absolute;
 /* display: none; */
 left: -999rpx;
 z-index: 0;
}

裁剪比例的样式,1:1裁剪使用750rpx,3:4使用padding进行视觉上的拉长
接下来就是重要的代码部分了

js文件

cutPic() {
 const _this = this
 if (this.data.cutting) {
  return
 }
 let promiseList = [], ctx = []
 _this.data.imgList.forEach((v, i) => {
  promiseList.push(_this.draw(ctx, v, i))
 })
 wx.showLoading({
  title: '截取中...',
  icon: 'none'
 })
 this.setData({
  cutting: true
 })
 Promise.all(promiseList).then((arr) => {
  wx.setStorageSync("interimImagesList", _this.data.imgFileList)
  _this.uploadPic()
 }, err => {
 })
 },

使用微信自带api,wx.chooseImage将图片保存在imgList数组里,因为裁剪图片用canvas处理会有一定的延迟,所以使用promise进行异步处理

//获取竖向滑动坐标
 endTou(e) {
 const _this = this
 let y = 'y[' + (_this.data.currentIndex - 1) + '].top'
 _this.setData({
  [y]: e.detail.scrollTop
 })
 },

定义的y数组用于记录每张图片截取的位置。

//绘制
 draw(ctx, v, i) {
 const _this = this
 let width, height
 return new Promise((resolve, reject) => {
  ctx[i] = wx.createCanvasContext(`myCanvas_${i}`)
  wx.getImageInfo({
  src: v,
  success: function (res) {
   width = 'width[' + i + ']'
   height = 'height[' + i + ']'
   var str = res.height / res.width;//图片的宽高比
   _this.setData({
   [width]: 375,
   [height]: 375 * str
   }, () => {
   ctx[i].drawImage(v, 0, 0, _this.data.width[i], _this.data.height[i])
   ctx[i].draw(false, () => {
    setTimeout(() => {
    wx.canvasToTempFilePath({//调用方法,开始截取
     x: 0,
     y: _this.data.y[i] ? _this.data.cutSelect == 1 ? _this.data.y[i].top : _this.data.y[i].top / 0.75 : 0,
     width: 375,
     height: _this.data.cutSelect == 1 ? 375 : 500,
     destWidth: 375,
     destHeight: _this.data.cutSelect == 1 ? 375 : 500,
     canvasId: 'myCanvas_' + i,
     success: function (res) {
     resolve(res.tempFilePath)
     console.info('canvas', res.tempFilePath)
     let img = 'imgFileList[' + i + ']'
     _this.setData({
      [img]: res.tempFilePath
     })
     },
     fail: function (err) {
     reject(err)
     console.info(err)
     }
    })
    }, 1000) // 渲染时间
   })
   })
  }
  })
 })
 },

渲染图片最重要的一步是获得宽高比,所以在canvas绘制之前使用getImageInfo获取到图片信息,var str=res.height/res.width获得高宽比例。

canvas绘制图片是需要时间,所以setTime了个1秒,不然截出来的图是失败的。这里也可以使用递归的方式来绘制

canvas 代码就不给出了,可以自己搜一下。

总结

一个简单的canvas截图就制作完成了。值得注意的是canvas渲染是需要时间的。
这也算是一个简单的练手吧,下次有什么复杂的截图功能再分享出来吧。

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

Javascript 相关文章推荐
北京奥运官方网站幻灯切换效果flash版打包下载
Jan 30 Javascript
jquery text,radio,checkbox,select操作实现代码
Jul 09 Javascript
Mootools 1.2教程(21)——类(二)
Sep 15 Javascript
js操作二级联动实现代码
Jul 27 Javascript
在网站上应该用的30个jQuery插件整理
Nov 03 Javascript
jquery遍历之parent()和parents()的区别及parentsUntil()方法详解
Dec 02 Javascript
jquery动态加载js/css文件方法(自写小函数)
Oct 11 Javascript
打造自己的jQuery插件入门教程
Sep 23 Javascript
Vue 换肤的示例实践
Jan 23 Javascript
vue 指令之气泡提示效果的实现代码
Oct 18 Javascript
layui-table对返回的数据进行转变显示的实例
Sep 04 Javascript
vue @click.native 绑定原生点击事件
Apr 22 Vue.js
小程序实现分类页
Jul 12 #Javascript
jquery实现自定义树形表格的方法【自定义树形结构table】
Jul 12 #jQuery
小程序实现搜索框
Jun 19 #Javascript
ECharts地图绘制和钻取简易接口详解
Jul 12 #Javascript
vue cli安装使用less的教程详解
Jul 12 #Javascript
Js通过AES加密后PHP用Openssl解密的方法
Jul 12 #Javascript
django js 实现表格动态标序号的实例代码
Jul 12 #Javascript
You might like
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
jQuery获取文本节点之 text()/val()/html() 方法区别
2011/03/01 Javascript
关于JavaScript的面向对象和继承有利新手学习
2013/01/11 Javascript
6款经典实用的jQuery小插件及源码(对话框/提示工具等等)
2013/02/04 Javascript
AngularJS页面访问时出现页面闪烁问题的解决
2016/03/06 Javascript
Vue.js基础知识小结
2017/01/13 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
d3.js实现立体柱图的方法详解
2017/04/28 Javascript
js is_valid_filename验证文件名的函数
2017/07/19 Javascript
在 Node.js 中使用原生 ES 模块方法解析
2017/09/19 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
webpack+vue-cli项目中引入外部非模块格式js的方法
2018/09/28 Javascript
使用express来代理服务的方法
2019/06/21 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
vue之a-table中实现清空选中的数据
2019/11/07 Javascript
JS三级联动代码格式实例详解
2019/12/30 Javascript
js+canvas实现简单扫雷小游戏
2021/01/22 Javascript
vue3.0中使用element的完整步骤
2021/03/04 Vue.js
Python使用三种方法实现PCA算法
2017/12/12 Python
Python中查看变量的类型内存地址所占字节的大小
2019/06/26 Python
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
使用Python函数进行模块化的实现
2019/11/15 Python
使用Python的Turtle库绘制森林的实例
2019/12/18 Python
python如何获得list或numpy数组中最大元素对应的索引
2020/11/16 Python
CSS3中currentColor关键字的妙用
2016/02/27 HTML / CSS
英国排名第一的LED灯泡网站:LED Bulbs
2019/09/03 全球购物
HSRP的含义以及如何工作
2014/09/10 面试题
建筑人员岗位职责
2013/12/25 职场文书
创业计划实施的7大步骤
2014/02/05 职场文书
电厂职工自我鉴定
2014/02/20 职场文书
2014年营业员工作总结
2014/11/18 职场文书
事业单位聘任报告
2015/03/02 职场文书
幼儿园教师师德表现自我评价
2015/03/05 职场文书
预备党员考察意见范文
2015/06/01 职场文书
教师反邪教心得体会
2016/01/15 职场文书
kubernetes集群搭建Zabbix监控平台的详细过程
2022/07/07 Servers