iOS中实现动态区域裁剪图片功能实例

2020-01-21 02:34:44王振洲

其中 fillRule 属性表示使用哪一种算法去判断画布上的某区域是否属于该图形“内部”,内部区域将被填充颜色,主要有两种方式

kCAFillRuleNonZero,这种算法判断规则是,如果从某一点射出任意方向射线,与对应 Layer 交点为 0 则不在 Layer 内,大于 0 则在 画布内

ios,裁剪屏幕指定区域,裁剪图片指定区域,图片裁剪

kCAFillRuleEvenOdd 如果从某一点射出任意射线,与对应 Layer 交点为偶数则在画布内,否则不在画布内

ios,裁剪屏幕指定区域,裁剪图片指定区域,图片裁剪

再给 CAShapeLayer 设置蒙层颜色为透明度 0.5 的黑色,就可以实现空心蒙层效果了。

最后就是设置 layer 的四个属性并绘制内边框的白色边线。


 [layer setCropAreaLeft:self.cropAreaX CropAreaTop:self.cropAreaY CropAreaRight:self.cropAreaX + self.cropAreaWidth CropAreaBottom:self.cropAreaY + self.cropAreaHeight];
 [self.cropView.layer addSublayer:layer];
 [self.view bringSubviewToFront:self.cropView];

合理放置图片

到这一步我们正确显示了图片,也正确显示出了裁剪区域,但是我们没有将二者的约束关系建立起来,因此可能会出现下面这样的情况

ios,裁剪屏幕指定区域,裁剪图片指定区域,图片裁剪

可以看到这里由于这张图片的 width 远大于 height,因此会在裁剪区域内出现黑色区域,这对用户来说是一种不好的体验,同时也会影响到我们后面的裁剪步骤,究其原因是因为我们没有针对裁剪区域的宽高来放置 UIImageView,我们希望最理想的效果是,能在裁剪区域内实现类似 UIViewContentModeScaleAspectFill 的效果,也就是图片保持比例地铺满裁剪区域,并允许部分内容超出裁剪区域,这就要求

当图片宽与裁剪区域宽之比大于图片高与裁剪区域高之比时,将图片高铺满裁剪区域高,图片宽成比例放大 当图片高与裁剪区域高之比大于图片宽与裁剪区域宽之比时,将图片宽铺满裁剪区域宽,图片高成比例方法

这里我们用到 Masonry 来做这些布局操作


 CGFloat tempWidth = 0.0;
 CGFloat tempHeight = 0.0;
 
 if (self.targetImage.size.width/self.cropAreaWidth <= self.targetImage.size.height/self.cropAreaHeight) {
 tempWidth = self.cropAreaWidth;
 tempHeight = (tempWidth/self.targetImage.size.width) * self.targetImage.size.height;
 } else if (self.targetImage.size.width/self.cropAreaWidth > self.targetImage.size.height/self.cropAreaHeight) {
 tempHeight = self.cropAreaHeight;
 tempWidth = (tempHeight/self.targetImage.size.height) * self.targetImage.size.width;
 }
 
 [self.bigImageView mas_updateConstraints:^(MASConstraintMaker *make) {
 make.left.mas_equalTo(self.cropAreaX - (tempWidth - self.cropAreaWidth)/2);
 make.top.mas_equalTo(self.cropAreaY - (tempHeight - self.cropAreaHeight)/2);
 make.width.mas_equalTo(tempWidth);
 make.height.mas_equalTo(tempHeight);
 }];