热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

微信小程序之裁剪图片成圆形的实现代码

最近在开发小程序,产品经理提了一个需求,要求微信小程序换头像,用户剪裁图片必须是圆形。这篇文章主要介绍了微信小程序之裁剪图片成圆形,需要的朋友可以参考下

前言

最近在开发小程序,产品经理提了一个需求,要求微信小程序换头像,用户剪裁图片必须是圆形,也在github上看了一些例子,一般剪裁图片用的都是方形,所以自己打算写一个小组件,可以把图片剪裁成圆形,主要思路就是使用canvas绘图,把剪裁的图片绘制成圆形,另外剪裁图片的窗口还可以移动放大缩小,这个功能就用了微信组件movable-view,好了,该说的也说完了,下面咱们开始撸代码。

movable-view组件

可移动的视图容器,在页面中可以拖拽滑动

会有好多个属性,在这里不一一介绍,只说我们能用到的就可以。

我们用到的属性主要有:

1.direction:movable-view的移动方向,属性值有all、vertical、horizontal、none

2.scale:是否支持双指缩放,默认缩放手势生效区域是在movable-view内

3.scale-min 定义缩放倍数最小值

4.scale-max 定义缩放倍数最大值

5.bindchange 拖动过程中触发的事件,event.detail = {x: x, y: y, source: source},其中source表示产生移动的原因,值可为touch(拖动)、touch-out-of-bounds(超出移动范围)、out-of-bounds(超出移动范围后的回弹)、friction(惯性)和空字符串(setData)

6.bindscale 缩放过程中触发的事件,event.detail = {x: x, y: y, scale: scale},其中x和y字段在2.1.0之后开始支持返回

主要用到的就是这几个值

另外使用movable-view的时候必须在外边加一个movable-area的父元素,不然的话没有移动区域。

movable-view 的可移动区域,属性只有:

scale-area 当里面的movable-view设置为支持双指缩放时,设置此值可将缩放手势生效区域修改为整个movable-area,是个boolean值,默认false

截取区域的移动已经说完了,详情请看传送门

canvas绘图

画布。该组件是原生组件可以绘制图像,分享朋友圈生成海报就经常用到这个属性,就简单的说下:

在wxml中必须要有canvas这个标签,才可以绘制图像,而且要有canvas-id属性,代表canvas 组件的唯一标识符,
还有许多API我就不一一介绍了,底下用的API代码当中都会用注释。详情请看微信小程序画布API传送门

代码实现

1.首先是选择图片

wxml就是初始化一个按钮点击的时候选择图片,而且需要引入我们封装的截取图片组件,并把图片作为参数传进去,封装组件方法请看我另一篇文章组件封装

index.wxml

Tip: 必须把canvas放到引入剪裁组件的wxml中,否则绘制不成功,因为canvas是原生组件脱离在 WebView 渲染流程外。


 
 
  
 

index.json引入截取图片的组件

{
 "component": true,
 "usingComponents": {
  "ClipImg": "../../component/clipImg/clipImg"
 }
}

index.js上传图片显示

const app = getApp()

Page({
 data: {
 imgSrc: ''
 },
 //选择图片
 getImgurl: function () {
 wx.chooseImage({
  count: 1, // 默认9
  sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
  sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
  success: (res) => {
  // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
  const tempFilePaths = res.tempFilePaths;
  //启动上传等待中... 
  wx.showToast({ 
   title: '正在上传...', 
   icon: 'loading', 
   mask: true, 
   duration: 1000 
  }) 
  this.setData({
   imgSrc: res.tempFilePaths
  })
  }
 })
 },
 onLoad: function () {
 }
})

接下来就是剪裁图片组件的封装

首先是页面布局,也就是clipImg.wxml


 
 
  
  
 
 
  取消
  保存
 

大概就是这个样子

上边的圆就是截取就是截取框。

然后就是clipImg.js文件主要就是对图片截取的一些操作

Component({
 /**
 * 组件的属性列表
 */
 properties: {
 imgSrc: {
  type: 'String',
  value: ''
 }
 },
 /**
 * 组件的初始数据
 * imageUrl string 初始化图片
 * cropperW string 缩小图宽度
 * cropperH string 缩小图高度,
 * img_ratio string 图片比例,
 * IMG_W string 原图高度,
 * IMG_H string 原图高度,
 * left string 图片距离左边距离,
 * top string 图片距离上边距离,
 * clipW number 默认截取框
 */
 data: {
 imageUrl: '',
 cropperW: '',
 cropperH: '',
 img_ratio: '',
 IMG_W: '',
 IMG_H: '',
 left: '',
 top: '',
 clipW: 200
 },
 /**
 * 组件的方法列表
 */
 methods: {
 //点击取消
 cancel: function () {
  var myEventDetail = {} // detail对象,提供给事件监听函数
  var myEventOption = {} // 触发事件的选项
  this.triggerEvent('myevent', myEventDetail, myEventOption)
 },
 //拖拽事件
 move: function ({ detail }) {
  this.setData({
  left: detail.x * 2,
  top: detail.y * 2
  })
 },
 //缩放事件
 scale: function ({ detail }) {
  console.log(detail.scale)
  this.setData({
  clipW: 200 * detail.scale
  })
 },
 //生成图片
 getImageInfo: function () {
  wx.showLoading({
  title: '图片生成中...',
  })
  const img_ratio = this.data.img_ratio;
  //要截取canvas的宽
  const canvasW = (this.data.clipW / this.data.cropperW) * this.data.IMG_W
  //要截取canvas的高
  const canvasH = (this.data.clipW / this.data.cropperH) * this.data.IMG_H
  //要截取canvas到左边距离
  const canvasL = (this.data.left / this.data.cropperW) * this.data.IMG_W
  //要截取canvas到上边距离
  const canvasT = (this.data.top / this.data.cropperH) * this.data.IMG_H
  // 将图片写入画布
  const ctx = wx.createCanvasContext('myCanvas');
  //绘制图像到画布
  ctx.save(); // 先保存状态 已便于画完圆再用  
  ctx.beginPath(); //开始绘制 
  ctx.clearRect(0, 0, 1000, 1000)
  //先画个圆  
  ctx.arc(this.data.clipW / 2, this.data.clipW / 2, this.data.clipW / 2, 0, 2 * Math.PI, false)
  ctx.clip();//画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 
  ctx.drawImage(this.data.imageUrl, canvasL, canvasT, canvasW, canvasH, 0, 0, this.data.clipW, this.data.clipW); // 推进去图片  
  ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 可以继续绘制
  ctx.draw(true, () => {
  // 获取画布要裁剪的位置和宽度 
  wx.canvasToTempFilePath({
   x: 0,
   y: 0,
   width: this.data.clipW,
   height: this.data.clipW,
   destWidth: this.data.clipW,
   destHeight: this.data.clipW,
   quality: 0.5,
   canvasId: 'myCanvas',
   success: (res) => {
   wx.hideLoading()
   /**
    * 截取成功后可以上传的服务端直接调用
    * wx.uploadFile();
    */
   //成功获得地址的地方
   wx.previewImage({
    current: '', // 当前显示图片的http链接
    urls: [res.tempFilePath] // 需要预览的图片http链接列表
   })
   }
  })
  })
 }
 },
 ready: function () {
 this.setData({
  imageUrl: this.data.imgSrc[0]
 })
 //获取图片宽高
 wx.getImageInfo({
  src: this.data.imageUrl,
  success: (res) => {
  console.log('图片信息', res);
  //图片实际款高
  const width = res.width;
  const height = res.height;
  //图片宽高比例
  const img_ratio = width / height
  this.setData({
   img_ratio,
   IMG_W: width,
   IMG_H: height,
  })
  if (img_ratio >= 1) {
   //宽比较大,横着显示
   this.setData({
   cropperW: 750,
   cropperH: 750 / img_ratio,
   })
  } else {
   //竖着显示
   this.setData({
   cropperW: 750 * img_ratio,
   cropperH: 750
   })
  }
  } 
 })
 }
})

到现在为止一个截取图片就完成了,可能会有些问题,比如截取的图片的框没有居中,自己可以再次封装这个组件,因为现在已经适合我们公司自己项目了。我们来预览下。另外这个组件支持双指放大截取框来截取图片,不过微信开发者工具不能展示,自己可以把代码下载下来,在自己手机上扫码查看效果。


另外我把项目放到了github上边,希望小哥哥小姐姐们多多点赞,多多支持,有什么疑问可以在github上问我,谢谢。点赞的小哥哥小姐姐最可爱,哈哈哈。。。

项目地址链接描述

推荐:

感兴趣的朋友可以关注小编的微信公众号【码农那点事儿】,更多网页制作特效源码及学习干货哦!!!

总结

以上所述是小编给大家介绍的微信小程序之裁剪图片成圆形的实现代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 校园表白墙微信小程序,校园小情书、告白墙、论坛,大学表白墙搭建教程
    小程序的名字必须和你微信注册的名称一模一样在后台注册好小程序。mp.wx-union.cn后台域名https。mp.wx-union.cn ... [详细]
  • 来自微信官方:微信支付跨平台软件架构首次曝光
    大纲背景线上效果指标什么是软件架构为什么需要软件架构从零到一构建支付跨平台软件架构1.抽象业务流程2.加入路由机制3.管理网络请求4.规范数据传递总结背景作为一个重要业务ÿ ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 微信答题小程序的设计与实现详解
    本文详细介绍了如何设计和实现一个微信答题小程序,包括题库的设计和题目的呈现。通过抽取题目编号和使用全局变量记录当前题目的信息,实现了题目的刷新和显示。同时,还介绍了题目的展示方式和容器的创建。本文适合零基础的小白学习微信答题小程序的开发。 ... [详细]
  • 微信小程序导航跟随的实现方法
    本文介绍了在微信小程序中实现导航跟随的方法。通过设置导航的position属性和绑定滚动事件,可以实现页面向下滚动到导航位置时,导航固定在页面最上方;页面向上滚动到导航位置时,导航恢复到原始位置;点击导航可以平滑跳转到相应位置。代码示例也给出了具体实现方法。 ... [详细]
  • 微信民众号商城/小顺序商城开源项目介绍及使用教程
    本文介绍了一个基于WeiPHP5.0开发的微信民众号商城/小顺序商城的开源项目,包括前端和后端的目录结构,以及所使用的技术栈。同时提供了项目的运行和打包方法,并分享了一些调试和开发经验。最后还附上了在线预览和GitHub商城源码的链接,以及加入前端交流QQ群的方式。 ... [详细]
  • 使用flex弹性布局来为微信小程序写自适应页面
    我们知道,写习惯了前端的人,一般切图后布局页面的话,上手最习惯的是基于盒子模型的浮动布局,依赖display属性positi ... [详细]
  • remote 移除_remote模块的使用(四)
    微信公众号:[猫十二的日常],欢迎留言和指出问题a在electron中的一些模块,它是区分进程的,有些模块只能是主进程可以使 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 微信开放外链的第二阶段:腾讯和阿里巴巴的博弈
    2021年11月30日,微信开始进行“开放外链”的第二阶段,允许在微信个人会话中打开外部链接和在微信群中打开电商链接。虽然这是腾讯和阿里巴巴都能接受的阶段性结果,但双方都不会太满意。接下来几个月,腾讯和阿里将展开复杂的博弈,我们作为外人很难看清全过程。工信部从未要求腾讯无条件开放微信API,本次开放的也只是普通的HTTP链接。 ... [详细]
author-avatar
瓶子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有