自定义图片裁剪之双指缩放思路

2,139 阅读4分钟
  1. 前一段时间产品经理就着图片裁剪的功能找到我:小哥,这个图片裁剪怎么在华为手机上是一个圆形,而小米手机上是一个正方形啊;我说:是啊,咱用的是系统自带的图片裁剪功能,不同厂商对Google的裁剪框做了定制化,即使同一厂商的不同型号手机也有可能不一致,而使用系统的裁剪效果可以完美适配所有手机,不存在兼容性问题;产品经理说这样不行,噼里啪啦列了一堆不统一的坏处,结果就是我要自定义图片裁剪功能。

  2. 自定义裁剪就自定义裁剪,不就是一个图片加一个可移动的框吗,看我的。花了大概10分钟的时间从github上找一个非常厉害的图片裁剪库cropper,这个库大效果是这样的:按住裁剪中心,可随意拖动到图片的任何位置;按住裁剪框四个角,可放到缩小剪裁框; 还可以设置裁剪框初始大小以及等比缩放。嗯,就它了,于是我把这个库引入到项目中,看着图片裁剪的效果心里美滋滋。

  3. 又过了一段时间,产品经理找我:小哥,你这个图片裁剪功能有点不对劲啊,怎么只能拖动不能缩放呢?我说可以啊,你拖动四个角不就可以缩放吗。但我要的是两个指头进行缩放;哦,这样啊,我先看看,看了一下微信的图片裁剪和一些手机系统的裁剪功能大致可分为3类:第一类手机不支持双指缩放,第二类手机双指缩放背景图片(主流),第三类手机双指缩放裁剪框;经过和产品经理一番讨论,决定做成双指缩放裁剪框。

  4. 终于进入今天的主题了,其实自定义图片裁剪功能不能,处理好图片显示和触摸事件,剩下的没啥了,cropper这个库在这个基础上做了大量的封装;一些设计模式的运用和代码的封装很值得我们学习,具体的我就不分析了,网上有大神对这一块分析得很详细,我就补充一下cropper库没有的双指缩放功能。

  5. 双指缩放主要涉及到oTouchEvent事件,平常我们处理触摸事件,都是处理ACTION_DOWN、ACTION_MOVE、ACTION_UP这三个事件,如果多手指就得处理新增ACTION_POINTER_DOWN和ACTION_POINTER_UP事件,每次执行ACTION_POINTER_DOWN事件时就相当于有新的手指触摸屏幕,执行ACTION_POINTER_UP事件时就等于有额外的手指离开屏幕,通过这两个事件我们可以准确得出ACTION_MOVE事件执行时有几个手指在屏幕上,接下来当有多个手指在屏幕上时,我们可通过getX(0)、getX(1)、getX(2)...来获取每个手指在屏幕上的坐标,由于我们只处理双指缩放,所以这里只取第一个和第二个手指的坐标,根据每次执行的ACTION_MOVE事件时,两个坐标之间距离的变化,来判断用户是想放大还是缩小。

  6. 我第一次使用的是两个坐标之间的距离变化来放大缩小裁剪框,由于宽和高都是缩放距离差的一半,所以每次都是等比缩放,这样有些不符用户习惯,比如用户两个手指分别沿Y轴缩放,裁剪框还是会缩放等比缩放宽和高,后面做了一些改进;改成X坐标的差值和Y坐标的差值分别缩放裁剪框的宽和高,这样使用起来比较顺手。

  7. 无论双指是缩放裁剪框还是缩放背景图,都可以使用上述的思路来处理,当然这只是思路,具体实现还得根据效果来微调,例如缩放框时,根据双指缩放的距离来缩放框,导致裁剪框缩放速度太慢,我们会给缩放值乘以缩放因子,适当调节达到符合用户使用的效果;缩放背景图时,如果缩小图片,会导致裁剪框超出图片大小,这里也要做适当的调整。这里由于demo是在公司实现的,写博客时就没有贴出代码实现,相信读过一遍这个实现思路,慢慢自己写出具体效果应该不难。