微信小程序图片九宫格裁剪功能的代码实现,前端宫格裁剪图片

发布用户:小梦

2022/11/26 18:48


此代码功能原用于已上线的图片圈子小程序 — 创艺有图,不过很可惜,目前该小程序已下线,下面是完整代码的展现效果图:

功能是用户选择手机里的图片后可以拖动位置进行方块功能裁剪,有九宫格和四宫格,裁剪是一键完成的,而且很快,但不支持缩放。

点击裁剪按钮后会跳到裁剪后的图片格子页,在这页中可以选择单张保存或是一键保存;和网页中不一样,一件保存是微信小程序的特有功能,不必制成压缩包,很方便;下面是步骤拆分:

  • 使用了微信小程序组件 movable-areamovable-view
  • 待剪图片上的网格和遮罩是通过元素标记加样式表组成的
  • 使用微信小程序组件 canvas 和其相关的 API 实现的裁剪
  • 裁剪完后以本地的临时图像显示在图片元素里

裁剪关键代码:

var that = this
var selected_counts = that.data.selected_counts
var column = selected_counts == 4 ? 2 : 3
var short_width = that.data.pic_width <= that.data.pic_height ? that.data.pic_width : that.data.pic_height
const query = wx.createSelectorQuery()
query.select(''#myCanvas'')
   .fields({
       node: true,
       size: true
   })
   .exec((res2) => {
       const canvas = res2[0].node
       const ctx = canvas.getContext(''2d'')
       var cut_width = short_width / column
       canvas.width = cut_width
       canvas.height = cut_width
       var cut_x_start = Math.abs(that.data.trans_x)
       cut_x_start = that.data.scale_ratio < 1 ? cut_x_start / that.data.scale_ratio : cut_x_start * that.data.scale_ratio
       var cut_y_start = Math.abs(that.data.trans_y)
       cut_y_start = that.data.scale_ratio < 1 ? cut_y_start / that.data.scale_ratio : cut_y_start * that.data.scale_ratio
       const headerImg = canvas.createImage();
       headerImg.src = that.data.local_pic_url;
       headerImg.onload = () => {
           var pictures_cuted = that.data.pictures_cuted
           pictures_cuted = []
           that.setData({
               pictures_cuted: pictures_cuted
           })
           var cut_x = cut_x_start
           var cut_y = cut_y_start
           for (var i = 1; i <= selected_counts; i++) {
               ctx.drawImage(headerImg, cut_x, cut_y, cut_width, cut_width, 0, 0, cut_width, cut_width);
               if (i % column == 0) {
                   cut_x = cut_x_start
                   cut_y += cut_width
               } else {
                   cut_x += cut_width
               }
               wx.canvasToTempFilePath({
                   fileType: "jpg",
                   quality: 0.9,
                   canvas: canvas,
                   success(res) {
                       var pictures_cuted = that.data.pictures_cuted
                       pictures_cuted.push(res.tempFilePath)
                       that.setData({
                           pictures_cuted: pictures_cuted
                       })
                   }
               })
           }
       }
   })

可以知道裁剪的原理是根据用户拖动的位置与图片的大小和网格的大小综合计算绘制出来的,这里面有部分参数如图片根据手机屏幕的缩放比、图片宽高等需要在加载图片的步骤中提前设置好。

九网格的标记代码是:

<view id="view_grids_box_9">
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
   <view class="VIEW_grids"></view>
</view>

九宫格的样式表代码是:

#view_grids_box_9 {
   border: 1px solid #fff;
   box-sizing: border-box;
   position: absolute;
   width: 80vw;
   height: 80vw;
   top: calc(50% - 40vw);
   left: 10vw;
   pointer-events: none;
   z-index: 100;
   display: flex;
   flex-wrap: wrap;
}

   #view_grids_box_9 .VIEW_grids {
       border: 1px dashed rgba(250, 250, 250, .5);
       width: calc(100% / 3);
       position: relative;
       box-sizing: border-box;
   }

标记与样式表配合就实现了图片上覆盖的网格效果。在微信小程序组件 movable-view 中需要绑定移动改变事件 bindchange="moveAreaChange" 用于监测并保存图片被拖动的位置:

moveAreaChange: function (e) {
   this.setData({
       trans_x: e.detail.x,
       trans_y: e.detail.y
   })
}

在微信小程序中提供了一个 API 是 wx.saveImageToPhotosAlbum,调用这个接口轻松实现一键全部保存。



代码写多了,脑力不够用了,请我喝杯咖啡提提神 ☕

警告!禁止网络诈骗、非法集资、非法套现等法律外的缘由转账汇款,你的赞赏转账请考虑再三后支付,此收款不作任何形式的退款。





金额:

* 支付宝支付后如果没有自动返回请手动返回此页并刷新。



* 在线内容服务不支持任何形式的退款/退费操作;支付后的订单记录可以在“用户主页 - 用户订单中心”查看。

此网站可能不完全兼容您目前的浏览器!
此页随时可能被替换下线,请不要依赖此页功能!
此页正在维护更新,可能会出现错误或卡顿。
通知 & 公告

暂时还没有消息