位置: IT常识 - 正文

微信小程序图片裁剪功能的实现(微信小程序图片大小如何设置)

编辑:rootadmin
微信小程序图片裁剪功能的实现 文章目录图片上传与处理图片尺寸适配图片显示与裁剪框裁剪框的拖动与缩放增加canvas并裁剪图片保存图片到相册总结

推荐整理分享微信小程序图片裁剪功能的实现(微信小程序图片大小如何设置),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:微信小程序图片怎么转https链接,微信小程序图片显示不出来,微信小程序图片下载不了什么原因,微信小程序图片下载不了什么原因,微信小程序图片处理,微信小程序图片下载不了什么原因,微信小程序图片怎么下载,微信小程序图片显示不出来,内容如对您有帮助,希望把文章链接给更多的朋友!

在之前的博文中,已经介绍了如何使用在前端开发中,实现较方便自由的图片裁剪功能,可见博文:如何一步步实现图片裁剪功能。 本文将进一步讲述在微信小程序中,我们实现图片裁剪功能需要如何处理,文章末尾将附上小程序端图片裁剪完整源码的下载链接。 在小程序中进行图片裁剪的效果如下图所示:

图片上传与处理

要做图片裁剪,首先要解决的是图片上传的事情,这块在微信环境下,比较好处理,微信小程序提供了多个文件或图片的操作接口,让我们可以很方便的完成这个步骤。

本博之前关于小程序的图片审核的文章:小程序图片上传与内容安全审核,已介绍了使用 wx.chooseMedia 接口来选择图片文件。 除此外,还可以有其他方式,如 wx.chooseMessageFile 接口可以从聊天记录里选择图片,我们可以综合处理如下:

function selectPhoto (callBack) { let itemList = [ '拍照', '从手机相册选择', '从聊天记录选择' ] wx.showActionSheet({ itemList, success: (action) => { if (action.tapIndex === 0) { // 从拍照选择图片,使用 chooseMedia wx.chooseMedia({ sourceType: [ 'camera' ] }) } else if (action.tapIndex === 1) { // 从手机相册选择图片,使用 chooseMedia wx.chooseMedia({ sourceType: [ 'album' ] }) } else if (action.tapIndex === 2) { // 从聊天记录选择图片,使用 chooseMessageFile wx.chooseMessageFile({}) } } })}

其中,showActionSheet 可以显示操作菜单,这个功能也比较常见,可以从拍照、相册、聊天记录里选择文件进行加载:

当前,我们获取到的是图片文件的临时路径,得到图片路径以后,接下来要做的事情,就是如何正确适配的显示出来。

图片尺寸适配

由于要在前端对图片进行裁剪,使用canvas绘制图片也是不可少的,在绘制之前,我们需要根据图片尺寸进行适配处理。 首先需要做的就是读取图片的尺寸大小,使用小程序的 wx.getImageInfo 接口即可,它能够返回图片原始的宽高属性。 接着,根据图片的宽高属性、系统屏幕的宽高,一起在小程序页面可见区域内设置图片的缩放显示:

// 根据窗口大小和图片大小,设置图片显示尺寸以及缩放// imgHeight 和 imgWidth 表示当前图片的宽高// 设置图片显示面板的宽高let panelW = sys.windowWidth - 20let panelH = sys.windowHeight - 100if (panelH / panelW >= imgHeight / imgWidth) { panelH = parseInt(panelW * imgHeight / imgWidth)} else { panelW = parseInt(panelH * imgWidth / imgHeight)}// 图片在宽高上的缩放比,用于裁剪图片时计算图片实际尺寸xScale = panelW / imgWidthyScale = panelH / imgHeightthis.setData({ imagePath, // 图片显示面板宽高 panelWidth: panelW, panelHeight: panelH, // 裁剪框的宽高,初始时与图片面板一样 clipWidth: panelW, clipHeight: panelH, // 裁剪的实际宽高 croppingImageWidth: imgWidth, croppingImageHeight: imgHeight})

通过以上代码和注释,我们知道了图片加载时,需要计算的几个宽高尺寸值,都是比较重要的。

图片显示与裁剪框

下面就可以在页面上显示图片,直接展示图片显示区域的 wxml 代码:

<view wx:if="{{imagePath}}" class="crop-container"> <view class="crop-content" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}};"> <image src="{{imagePath}}" class="pos-absolute" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: 0; top:0;"/> <view class="mask-bg" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: 0; top: 0;"></view> <view class="clip-path" style="width: {{clipWidth + 'px'}}; height: {{clipHeight + 'px'}}; left: {{clipX + 'px'}}; top: {{clipY + 'px'}};"> <image src="{{imagePath}}" class="pos-absolute" style="width: {{panelWidth + 'px'}}; height: {{panelHeight + 'px'}}; left: {{clipImgX + 'px'}}; top: {{clipImgY + 'px'}};"/> </view> <view class="clip-box" bind:touchmove="touchmoveM" bind:touchstart="touchstartM" style="width: {{clipWidth + 'px'}}; height: {{clipHeight + 'px'}}; left: {{clipX + 'px'}}; top: {{clipY + 'px'}};"> <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="leftTop" class="corner-area left-top"></view> <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="rightTop" class="corner-area right-top"></view> <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="rightBottom" class="corner-area right-bottom"></view> <view capture-catch:touchmove="touchmove" capture-catch:touchstart="touchstart" data-id="leftBottom" class="corner-area left-bottom"></view> </view> </view></view>微信小程序图片裁剪功能的实现(微信小程序图片大小如何设置)

以上代码中,

.crop-content 外层增加图片面板,图片资源直接使用 <image> 组件加载,与外层面板宽高保持一致;.mask-bg 增加一个遮罩层,作为非裁剪区域的蒙层,以黑灰色透明度实现效果;.clip-path 于图片面板内部,设置图片的裁剪区域,这里使用的是CSS中的 clip-path 属性,内部加载一张图片,作为裁剪区域的图片显示; clip-path 属性之前已有博文介绍,可以查看 clip-path属性clip-box 设置裁剪框区域的四个corner角:左上、右上、右下和左下,里面四个元素对应这个四个角,可以对裁剪框进行缩放处理; 当然,我们也可以在各边的中间位置再加上操作区,那一共就是8个;.clip-path 图片裁剪区与 clip-box 裁剪框需要设置位置信息,用于在移动的时候进行定位。

通过设置对应的图片元素、蒙层、裁剪框等等,我们就已经完成了图片裁剪的结构布局了,具体可见下图所示:

图片裁剪框设置完成后,我们需要处理的就是裁剪框的拖动与缩放事件处理了。

裁剪框的拖动与缩放

上面的 wxml 代码中,在裁剪框的元素部分,已经增加了 touchstart 和 touchmove 等事件,用于在处理拖动和缩放等操作。 当我们实现裁剪框的拖动,只需要如下两个事件:

touchstartM (event) { const { clipX, clipY } = this.data const { pageX, pageY } = event.touches[0] // 获取鼠标点在裁剪框的内部位置信息 clipBoxMoveInnerX = pageX - clipX clipBoxMoveInnerY = pageY - clipY},touchmoveM (event) { const { pageX, pageY } = event.touches[0] const { panelWidth, panelHeight, clipHeight, clipWidth } = this.data // 裁剪框不能脱离面板 // X位置范围为 0 到 (面板宽度-裁剪框宽度) let clipX = pageX - clipBoxMoveInnerX clipX = Math.max(clipX, 0) const panelX = panelWidth - clipWidth clipX = Math.min(clipX, panelX) // Y位置范围为 0 到 (面板高度-裁剪框高度) let clipY = pageY - clipBoxMoveInnerY clipY = Math.max(clipY, 0) const panleY = panelHeight - clipHeight clipY = Math.min(clipY, panleY) // 裁剪框底图位置信息 const clipImgX = 0 - clipX const clipImgY = 0 - clipY this.setData({ clipX, clipY, clipImgX, clipImgY })}

以上代码,通过计算图片移动时的相对位移,重新计算裁剪框的新的位置信息,需要注意的是,移动时不要脱离外层的面板——即不能脱离图片区域,否则无效。

缩放的操作则相对复杂一些,需要计算位移移动的距离以及当前位置下的裁剪宽高数据,并且要对每个不同的corner角进行特殊处理,这块的完整代码和注释如下所示:

// 处理缩放动作中不同corner时的尺寸位置信息getClipX (clipWidth) { switch (activeCorner) { case 'leftTop': case 'leftBottom': return clipBoxBeforeScaleClipX + (clipBoxBeforeScaleWidth - clipWidth) case 'rightTop': case 'rightBottom': return clipBoxBeforeScaleClipX default: return 0 }},getClipY (clipHeight) { switch (activeCorner) { case 'leftTop': case 'rightTop': return clipBoxBeforeScaleClipY + (clipBoxBeforeScaleHeight - clipHeight) case 'leftBottom': case 'rightBottom': return clipBoxBeforeScaleClipY default: return 0 }},getScaleXWidthOffset (offsetW) { switch (activeCorner) { case 'leftTop': case 'leftBottom': return -offsetW case 'rightTop': case 'rightBottom': return offsetW default: return 0 }},getScaleYHeightOffset (offsetH) { switch (activeCorner) { case 'rightBottom': case 'leftBottom': return offsetH case 'rightTop': case 'leftTop': return -offsetH default: return 0 }},touchstart (event) { const dragId = event.currentTarget.dataset.id const { pageX, pageY } = event.touches[0] const { clipX, clipY, clipHeight, clipWidth } = this.data // 设置缩放时临时变量初始化值 activeCorner = dragId clipBoxBeforeScalePageX = pageX clipBoxBeforeScalePageY = pageY clipBoxBeforeScaleClipX = clipX clipBoxBeforeScaleClipY = clipY clipBoxBeforeScaleWidth = clipWidth clipBoxBeforeScaleHeight = clipHeight},touchmove (event) { const { pageX, pageY } = event.touches[0] const { panelWidth, panelHeight } = this.data // 缩放在X上的偏移 const xWidthOffset = this.getScaleXWidthOffset(pageX - clipBoxBeforeScalePageX) // 裁剪框最小宽度36 let clipWidth = Math.max(clipBoxBeforeScaleWidth + xWidthOffset, 36) // 设置缩放最大宽度,放大时不能超过面板、缩小时不能超过初始裁剪框 let tempPanelWidth = pageX > clipBoxBeforeScalePageX ? panelWidth - clipBoxBeforeScaleClipX : clipBoxBeforeScaleWidth + clipBoxBeforeScaleClipX // 设置裁剪框宽度 clipWidth = Math.min(clipWidth, tempPanelWidth) // 缩放在Y上的偏移 const yHeightOffset = this.getScaleYHeightOffset(pageY - clipBoxBeforeScalePageY) // 裁剪框最小高度36 let clipHeight = Math.max(clipBoxBeforeScaleHeight + yHeightOffset, 36) // 设置缩放最大高度,放大时不能超过面板、缩小时不能超过初始裁剪框 let tempPanelHeight = pageY > clipBoxBeforeScalePageY ? panelHeight - clipBoxBeforeScaleClipY : clipBoxBeforeScaleHeight + clipBoxBeforeScaleClipY // 设置裁剪框高度 clipHeight = Math.min(clipHeight, tempPanelHeight) // 裁剪框位置信息 let clipX = this.getClipX(clipWidth) let clipY = this.getClipY(clipHeight) // 裁剪框底图位置信息 let clipImgX = 0 - clipX let clipImgY = 0 - clipY this.setData({ clipWidth, clipHeight, clipX, clipY, clipImgX, clipImgY, croppingImageWidth: parseInt(clipWidth / xScale), croppingImageHeight: parseInt(clipHeight / yScale) })}

至此,图片裁剪的功能基本完成了,能够加载图片、设置裁剪框、拖动和缩放裁剪框大小,计算裁剪图片的尺寸等等。 就剩下如何真正剪裁图片了。

增加canvas并裁剪图片

要剪裁图片,我们在小程序使用canvas画布组件来处理,在页面上增加一个canvas元素:

<canvas id="main" canvasId="main" class="main-canvas" style="width: {{croppingImageWidth + 'px'}}; height: {{croppingImageHeight + 'px'}}"></canvas>

由于这个canvas只是用来对图片进行裁剪操作,并不需要显示出来,我们可以把它定位到视觉窗口以外,不影响可操作的界面元素。 给画布设置图片裁剪所需要的宽高,通过在同等宽高下绘制图片,就能导出图片:

wx.showLoading({ title: '正在裁剪...' })preCtx.clearRect(0, 0, imageWidth, imageHeight)const width = croppingImageWidthconst height = croppingImageHeightconst xPos = Math.abs(clipImgX / xScale)const yPos = Math.abs(clipImgY / yScale)// 绘制裁剪区内的图片到画布上preCtx.drawImage(imagePath, xPos, yPos, width, height, 0, 0, width, height)preCtx.save()preCtx.restore()const that = thispreCtx.draw(false, function () { setTimeout(() => { // 将画布导出为临时图片文件 wx.canvasToTempFilePath({ x: 0, y: 0, width, height, destWidth: width, destHeight: height, canvasId: 'main', success: (canRes) => { wx.hideLoading() that.initImage(width, height, canRes.tempFilePath) }, fail (err) { wx.hideLoading() console.log(err) } }) }, 200)})

如上代码所示,通过裁剪图片的真实宽高以及相对位置信息,通过canvas的 drawImage 方法,把图片的裁剪区域的内容绘制到画布上,此时,该画布就对应一张裁剪后的图片,我们只需要把画布导出成图片文件即可。 导出画布,使用 wx.canvasToTempFilePath 方法,用于将画布导出为图片临时图片文件,这个图片文件可以重新加载或者进行导出。

保存图片到相册

以上过程,生成裁剪图片的临时文件后,就可以使用小程序提供的API,将图片文件保存到相册中。 只需要使用 wx.saveImageToPhotosAlbum 方法,专门用于将图片文件保存到系统相册,接收临时文件作为参数:

wx.saveImageToPhotosAlbum({ filePath: imgSrc, success: () => { wx.hideLoading() wx.vibrateShort() wx.showModal({ content: '图片已保存到相册~', showCancel: false, confirmText: '好的', confirmColor: '#333' }) }})

该方法简单方便,其中使用 wx.vibrateShort() 方法,作用是使手机发生较短时间的振动(15 ms),在小程序中也是常见的功能。 图片保存到系统相册功能完成后,我们就实现了在小程序中进行图片剪裁的完整功能,包含加载图片、图片适配和裁剪框绘制、裁剪框拖动与缩放事件、图片导出和保存的过程。

总结

本文详细讲述了在小程序中实现一个图片裁剪功能的过程,可以看出和在浏览器Web端的实现差别并不大。 在核心的图片适配、裁剪框绘制与缩放事件处理上,基本两边可以通用,在小程序中的实现逻辑可以完整在移到web浏览器上,反之亦然。 区别可能只在于图片的加载和保存上,可以使用小程序提供的多种内置接口方法,能较方便的完成。 上文也附上了大量的核心代码,根据这些代码已经基本可以还原裁剪功能,如果需要完整的小程序图片裁剪代码,可以访问下载:小程序图片裁剪源码下载

本文链接地址:https://www.jiuchutong.com/zhishi/298311.html 转载请保留说明!

上一篇:行人车辆检测与计数系统(Python+YOLOv5深度学习模型+清新界面)(行人检测技术)

下一篇:JavaWeb:实现购物商城(课程设计完整版)(javaweb购物)

  • 网站推广的有效宣传方式(网站推广的方法有哪几种)

    网站推广的有效宣传方式(网站推广的方法有哪几种)

  • soul怎么用小号找一个人(soul怎么用小号找人)

    soul怎么用小号找一个人(soul怎么用小号找人)

  • 拼多多的个人积分在哪(拼多多里的积分能干啥)

    拼多多的个人积分在哪(拼多多里的积分能干啥)

  • 拼多多店铺tab是什么意思

    拼多多店铺tab是什么意思

  • 一个人可以认证几个快手号(一个人可以认证几个小红书号)

    一个人可以认证几个快手号(一个人可以认证几个小红书号)

  • 笔记本语音自带麦吗 (笔记本语音怎么打开)

    笔记本语音自带麦吗 (笔记本语音怎么打开)

  • 解释程序产生了目标程序而汇编程序(解释程序出现问题为什么)

    解释程序产生了目标程序而汇编程序(解释程序出现问题为什么)

  • 华为的otg功能在哪里(华为的OTG功能在哪打开)

    华为的otg功能在哪里(华为的OTG功能在哪打开)

  • 爱奇艺超前点映是什么意思(爱奇艺超前点映什么时候可以看)

    爱奇艺超前点映是什么意思(爱奇艺超前点映什么时候可以看)

  • lq-630k打印机色带如何安装(lq-630k打印机色带芯如何安装)

    lq-630k打印机色带如何安装(lq-630k打印机色带芯如何安装)

  • 蓝牙绝对音量什么意思(蓝牙绝对音量功能)

    蓝牙绝对音量什么意思(蓝牙绝对音量功能)

  • 5g手机进网试用是什么意思(5g手机进网试用什么意思)

    5g手机进网试用是什么意思(5g手机进网试用什么意思)

  • 樱花动漫一直加载不出来怎么办(樱花动漫加载不进去)

    樱花动漫一直加载不出来怎么办(樱花动漫加载不进去)

  • qq怎么隐藏点赞数(qq怎么隐藏点赞数量)

    qq怎么隐藏点赞数(qq怎么隐藏点赞数量)

  • iphone4s怎么截长图(苹果4截图怎么截)

    iphone4s怎么截长图(苹果4截图怎么截)

  • 怎么把qq好友导入微信(怎么把qq好友导入电脑)

    怎么把qq好友导入微信(怎么把qq好友导入电脑)

  • id为什么自己锁了(为什么iphoneid会锁定)

    id为什么自己锁了(为什么iphoneid会锁定)

  • 苹果手机apple id建议验证失败(苹果手机apple id无法退出登录)

    苹果手机apple id建议验证失败(苹果手机apple id无法退出登录)

  • 优学派u36上市时间(优学派2021新款上市)

    优学派u36上市时间(优学派2021新款上市)

  • iphone 11支持双卡吗(iphone11支持双卡双待吗)

    iphone 11支持双卡吗(iphone11支持双卡双待吗)

  • 小米手环有测血压功能吗(小米手环有测血氧准的功能吗)

    小米手环有测血压功能吗(小米手环有测血氧准的功能吗)

  • 淘宝五皇冠可靠吗(淘宝五皇冠多少销量)

    淘宝五皇冠可靠吗(淘宝五皇冠多少销量)

  • 苹果私密相册怎么弄(苹果私密相册怎么打开)

    苹果私密相册怎么弄(苹果私密相册怎么打开)

  • qq群全员禁言怎么回事(qq群全员禁言怎么解除)

    qq群全员禁言怎么回事(qq群全员禁言怎么解除)

  • 华为p20pro红外线功能在哪(华为p20pro红外线遥控功能在哪里)

    华为p20pro红外线功能在哪(华为p20pro红外线遥控功能在哪里)

  • 微信怎样不显示地区(微信怎样不显示朋友圈这一栏)

    微信怎样不显示地区(微信怎样不显示朋友圈这一栏)

  • QQ如何在聊天群里艾特他人(qq聊天怎么群发消息)

    QQ如何在聊天群里艾特他人(qq聊天怎么群发消息)

  • 两年前的微信记录删了可以找到吗(两年前的微信记录)

    两年前的微信记录删了可以找到吗(两年前的微信记录)

  • 旅游业成本具体有哪些
  • 公司缴纳养老保险不在个人账户里吗
  • 如何开银行卡账户
  • 发票红票和退票区别在哪
  • 设备5年直线法计提折旧怎么做
  • 劳务公司涉及的税收
  • 六大往来科目重分类分录
  • 金税盘锁死提示什么
  • 附加税减免所得税汇缴的时候需要调整吗
  • 一般纳税人免征教育费附加的文件
  • 个人借款给公司利息收入要交税吗
  • 按季度支付贷款利息权责发生制
  • 现金日记账划线更正法
  • 转让专利属于什么分配
  • 行政单位明细账包括哪些
  • 债务重组与资产重组
  • 冲减预提费用
  • 发现财务人员违法怎么办
  • 投资收益的表现形式
  • 增值税附加税计入什么会计科目
  • 银行汇款风险提示
  • 油卡充值属于什么行业
  • 生产企业出口退税操作流程视频
  • 研发和技术服务在开票软件中怎么找
  • 开具的红字发票金税三期怎么报税?
  • 坏账损失做哪个科目
  • 抵扣发票勾选到哪个科目
  • 小规模销项负数发票怎么做账
  • 道路工程施工机械
  • 应付职工薪酬年底怎么结转
  • cmos电池耗尽
  • 个人去税务局开租房发票需要缴纳多少税点
  • 公司购买基金怎样入账
  • 怎么用U盘装系统win7
  • 出租商品计入其他业务收入吗
  • 前端字符长度限制
  • 员工食堂餐费可以税前扣除吗
  • ant-design-vue pro
  • 年度一次性计税
  • 月末季末年末会计都需要做什么
  • 会计政策变更对财务分析的影响
  • 车辆购置税发票图片
  • vue项目中技巧知识点
  • php 编码
  • 借方和贷方是什么意思 现金日记账
  • 成本票和费用票一样吗
  • 公司买办公用品是谁的工作
  • 简述跨期摊提账户
  • 利息发票可以抵扣吗
  • 建筑公司包含哪些业务
  • 基本户理财产品有哪些
  • db management
  • 资产处置损益影响损益吗
  • 小型微利企业计算企业所得税
  • 以货物抵债的会计分录
  • 增值税为什么不用计提
  • 职工福利费计提标准是多少
  • 贴现帐务处理
  • 管理费用月底结转吗
  • 模具成本核算汇总表
  • 应记入营业外支出的科目核算是
  • 单位之间借款还款怎么写
  • 税交多了可以退吗
  • 贷款指标是什么意思
  • 工会经费不够
  • 固定资产的调整科目
  • Winserver2012下mysql 5.7解压版(zip)配置安装教程详解
  • windows8任务管理器在哪
  • macbook外接多个显示器
  • WIN7如何关闭自动关机
  • opensuse怎么安装软件
  • samsung s3 gt-19300 开发 键盘回车事件
  • 提高网页的效率的方法有
  • unity3d bim
  • javascript运用
  • node.js适用哪些场景
  • bash 入门
  • 江苏省内车辆迁入标准
  • 国地税改革意义
  • 镇江市税务局官网
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设