微信小程序简单的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 相关文章推荐
基于jquery实现状态限定编辑的代码
Feb 11 Javascript
js实现带搜索功能的下拉框实时搜索实时匹配
Nov 05 Javascript
很棒的js选项卡切换效果
Jul 15 Javascript
ECMAScript6快速入手攻略
Jul 18 Javascript
JQ中$(window).load和$(document).ready区别与执行顺序
Mar 01 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
Jan 26 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
Mar 20 Javascript
js对象数组和对象的使用实例详解
Aug 27 Javascript
layui form.render('select', 'test2') 更新渲染的方法
Sep 27 Javascript
ES6扩展运算符和rest运算符用法实例分析
May 23 Javascript
如何通过Proxy实现JSBridge模块化封装
Oct 22 Javascript
Vite + React从零开始搭建一个开源组件库
Jun 25 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
在Zeus Web Server中安装PHP语言支持
2006/10/09 PHP
基于Zend的Captcha机制的应用
2013/05/02 PHP
thinkPHP学习笔记之安装配置篇
2015/03/05 PHP
PHP设计模式之工厂模式与单例模式
2016/09/28 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
js删除所有的cookie的代码
2010/11/25 Javascript
模拟jQuery ajax服务器端与客户端通信的代码
2011/03/28 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
2013/01/23 Javascript
angularjs学习笔记之双向数据绑定
2015/09/26 Javascript
jquery动态切换背景图片的简单实现方法
2016/05/14 Javascript
JavaScript中的操作符类型转换示例总结
2016/05/30 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
2016/07/07 Javascript
jQuery插件实现弹性运动完整示例
2018/07/07 jQuery
详解Python实现按任意键继续/退出的功能
2016/08/19 Python
关于Python中Inf与Nan的判断问题详解
2017/02/08 Python
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
Python科学计算包numpy用法实例详解
2018/02/08 Python
Python实现的简单读写csv文件操作示例
2018/07/12 Python
pygame游戏之旅 添加游戏介绍
2018/11/20 Python
详解django中url路由配置及渲染方式
2019/02/25 Python
python 实现turtle画图并导出图片格式的文件
2019/12/07 Python
Python try except异常捕获机制原理解析
2020/04/18 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
2020/05/13 Python
python中JWT用户认证的实现
2020/05/18 Python
HTML5 Canvas概述
2009/08/26 HTML / CSS
英国定做窗帘和纺织品面料一站式商店:Dekoria
2018/08/29 全球购物
Linux机考试题
2015/07/17 面试题
迟到检讨书400字
2014/01/13 职场文书
金融专业大学生职业生涯规划范文
2014/01/16 职场文书
市场推广策划方案
2014/06/02 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
群众路线批评与自我批评发言稿
2014/10/16 职场文书
2014年汽车销售工作总结
2014/12/01 职场文书
2014年基层党支部工作总结
2014/12/04 职场文书
电影建国大业观后感
2015/06/01 职场文书