微信小程序简单的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 实现AJAX加载XML并解析的脚本
Jul 25 Javascript
将函数的实际参数转换成数组的方法
Jan 25 Javascript
firefox火狐浏览器与与ie兼容的2个问题总结
Jul 20 Javascript
JavaScript使用Replace进行字符串替换的方法
Apr 14 Javascript
jQuery ui实现动感的圆角渐变网站导航菜单效果代码
Aug 26 Javascript
JS+DIV+CSS排版布局实现美观的选项卡效果
Oct 10 Javascript
jQuery解决浏览器兼容性问题案例分析
Apr 15 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
Sep 21 Javascript
3种不同的ContextMenu右键菜单实现代码
Nov 03 Javascript
JS同步、异步、延迟加载的方法
May 05 Javascript
详解如何在JS代码中消灭for循环
Dec 11 Javascript
Vue基于iview实现登录密码的显示与隐藏功能
Mar 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
PHP新手上路(十三)
2006/10/09 PHP
php绘图之生成饼状图的方法
2015/01/24 PHP
PHP Swoole异步Redis客户端实现方法示例
2019/10/24 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
Javascript 判断函数类型完美解决方案
2009/09/02 Javascript
jQuery中unbind()方法用法实例
2015/01/19 Javascript
jquery实现带缩略图的全屏图片画廊效果实例
2015/06/25 Javascript
js实现iPhone界面风格的单选框和复选框按钮实例
2015/08/18 Javascript
浅谈JS的基础类型与引用类型
2016/09/13 Javascript
AngularJS辅助库browserTrigger用法示例
2016/11/03 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
JS实现登录页密码的显示和隐藏功能
2017/12/06 Javascript
vue2.0 使用element-ui里的upload组件实现图片预览效果方法
2018/09/04 Javascript
node.js域名解析实现方法详解
2019/11/05 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
纯js+css实现仿移动端淘宝网站的弹出详情框功能
2019/12/29 Javascript
jQuery 隐藏/显示效果函数用法实例分析
2020/05/20 jQuery
openlayers实现地图测距测面
2020/09/25 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
Vue使用路由钩子拦截器beforeEach和afterEach监听路由
2020/11/16 Javascript
[09:23]国际邀请赛采访专栏:iG战队VK,Tongfu战队Cu
2013/08/05 DOTA
[02:35]DOTA2英雄基础教程 末日使者
2013/12/04 DOTA
[25:45]2018DOTA2亚洲邀请赛4.5SOLO赛 Sylar vs Paparazi
2018/04/06 DOTA
python实现在多维数组中挑选符合条件的全部元素
2019/11/26 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
2019/12/19 Python
基于Python共轭梯度法与最速下降法之间的对比
2020/04/02 Python
浅析关于Keras的安装(pycharm)和初步理解
2020/10/23 Python
Python实现图片指定位置加图片水印(附Pyinstaller打包exe)
2021/03/04 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
Kent & Curwen:与大卫·贝克汉姆合作
2017/06/13 全球购物
《三顾茅庐》教学反思
2014/04/10 职场文书
企业挂职心得体会
2014/09/10 职场文书
写景作文评语集锦
2014/12/25 职场文书
捐助感谢信
2015/01/22 职场文书
redis cluster支持pipeline的实现思路
2021/06/23 Redis