微信小程序简单的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 相关文章推荐
FileUpload上传图片(图片不变形)
Aug 05 Javascript
javascript中的float运算精度实例分析
Aug 21 Javascript
jquery getScript动态加载JS方法改进详解
Nov 15 Javascript
javascript的字符串按引用复制和传递,按值来比较介绍与应用
Dec 28 Javascript
jQuery.Validate验证库的使用介绍
Apr 26 Javascript
浅谈javascript属性onresize
Apr 20 Javascript
Javascript中arguments和arguments.callee的区别浅析
Apr 24 Javascript
在JavaScript中处理时间之getHours()方法的使用
Jun 10 Javascript
js图片轮播特效代码分享
Sep 07 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
Aug 15 Javascript
详解vue2.0监听属性的使用心得及搭配计算属性的使用
Jul 18 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
Nov 06 Javascript
小程序实现分类页
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
手冲咖啡应该是现代精品咖啡店的必备选项吗?
2021/03/03 冲泡冲煮
php面向对象全攻略 (四)构造方法与析构方法
2009/09/30 PHP
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
2012/10/05 PHP
PHP检测用户语言的方法
2015/06/15 PHP
thinkPHP+ajax实现统计页面pv浏览量的方法
2017/03/15 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
[原创]js与自动伸缩图片 自动缩小图片的多浏览器兼容的方法总结
2007/03/12 Javascript
JavaScript 给汉字排序实例代码
2008/06/28 Javascript
javascript中数组的多种定义方法和常用函数简介
2014/05/09 Javascript
JQuery创建DOM节点的方法
2015/06/11 Javascript
jQuery左侧大图右侧小图焦点图幻灯切换代码分享
2015/08/19 Javascript
webpack3+React 的配置全解
2017/08/21 Javascript
js如何找出字符串中的最长回文串
2018/06/04 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
vue组件开发之slider组件使用详解
2020/08/21 Javascript
结合axios对项目中的api请求进行封装操作
2020/09/21 Javascript
vue 基于abstract 路由模式 实现页面内嵌的示例代码
2020/12/14 Vue.js
node.js文件的复制、创建文件夹等相关操作
2021/02/05 Javascript
在Django的form中使用CSS进行设计的方法
2015/07/18 Python
Python简单定义与使用字典dict的方法示例
2017/07/25 Python
python实现windows壁纸定期更换功能
2019/01/21 Python
HTML5画渐变背景图片并自动下载实现步骤
2013/11/18 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
处理textarea中的换行和空格
2019/12/12 HTML / CSS
东方电视购物:东方CJ
2016/10/12 全球购物
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
类和结构的区别
2012/08/15 面试题
三月雷锋月活动总结
2014/07/03 职场文书
公司合作意向书范文
2014/07/30 职场文书
单位授权委托书范文
2014/08/02 职场文书
私人房屋买卖协议书
2014/10/04 职场文书
教师自查自纠材料
2014/10/14 职场文书
优秀班主任材料
2014/12/16 职场文书
爱晚亭导游词
2015/02/09 职场文书
2015年七一建党节慰问信
2015/03/23 职场文书
内勤岗位职责范本
2015/04/13 职场文书