微信小程序简单的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 相关文章推荐
Prototype1.6 JS 官方下载地址
Nov 30 Javascript
对js关键字命名的疑问介绍
Apr 25 Javascript
JS获取浏览器语言动态加载JS文件示例代码
Oct 31 Javascript
JavaScript实现带标题的图片轮播特效
May 20 Javascript
Bootstrap组件学习之导航、标签、面包屑导航(精品)
May 17 Javascript
JS实现星星评分功能实例代码(两种方法)
Jun 09 Javascript
BootStrap 实现各种样式的进度条效果
Dec 07 Javascript
Vue.js 插件开发详解
Mar 29 Javascript
vue 使用ref 让父组件调用子组件的方法
Feb 08 Javascript
node.js通过axios实现网络请求的方法
Mar 05 Javascript
Vue引用Swiper4插件无法重写分页器样式的解决方法
Sep 27 Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
Sep 21 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
ini_set的用法介绍
2014/01/07 PHP
thinkPHP使用post方式查询时分页失效的解决方法
2015/12/09 PHP
php7 安装yar 生成docker镜像
2017/05/09 PHP
tp5(thinkPHP5框架)captcha验证码配置及验证操作示例
2019/05/28 PHP
自己动手开发jQuery插件教程
2011/08/25 Javascript
可兼容IE的获取及设置cookie的jquery.cookie函数方法
2013/09/02 Javascript
javascript内存管理详细解析
2013/11/11 Javascript
JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍
2014/04/03 Javascript
js获取上传文件大小示例代码
2014/04/10 Javascript
js实现点击获取验证码倒计时效果
2021/01/28 Javascript
jQuery+CSS3实现3D立方体旋转效果
2015/11/10 Javascript
JS设置时间无效问题的解决办法
2017/02/18 Javascript
Vue.js实现文章评论和回复评论功能
2020/05/30 Javascript
JavaScript中splice与slice的区别
2017/05/09 Javascript
浅谈angular2 组件的生命周期钩子
2017/08/12 Javascript
对于input 框限定输入值为浮点型的js代码
2017/09/25 Javascript
微信小程序实现即时通信聊天功能的实例代码
2018/08/17 Javascript
Vue列表循环从指定下标开始的多种解决方案
2020/04/08 Javascript
js实现拖拽元素选择和删除
2020/08/25 Javascript
Python出现segfault错误解决方法
2016/04/16 Python
Python如何爬取微信公众号文章和评论(基于 Fiddler 抓包分析)
2019/06/28 Python
Python生命游戏实现原理及过程解析(附源代码)
2019/08/01 Python
python中的线程threading.Thread()使用详解
2019/12/17 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
Spartoo荷兰:鞋子、包包和服装
2018/07/12 全球购物
玉兰油美国官网:OLAY美国
2018/10/25 全球购物
什么是GWT的Module
2013/01/20 面试题
应届大专毕业生个人自荐信
2013/09/22 职场文书
结构工程研究生求职信
2013/10/13 职场文书
小学教师的个人自我鉴定
2013/10/24 职场文书
药品质量检测应届生求职信
2013/11/14 职场文书
2015年大学元旦晚会活动策划书
2014/12/09 职场文书
优秀教师先进事迹材料
2014/12/15 职场文书
我们的节日端午节活动总结
2015/02/11 职场文书
Java实现给Word文件添加文字水印
2022/02/15 Java/Android
nginx配置之并发频次限制
2022/04/18 Servers