java 截取图片指定区域,Quartz2D之截取图片指定区域 | 六阿哥博客

f95f31470d3c17afee010215fba5c8b3.gif

有些时候我们需要处理拍照后的图片截取操作,比如在上传用户头像的时候,用户上传的图片可能是很长的一张图片,但这样最后显示的头像就不会太完美。我们需要在用户上传头像的时候,有一个可以截取图片的功能。

需求分析

从上图直观看出,随着用户的触摸移动,会创建一个透明遮罩来表示需要截取的区域,然后截取了区域里的图片。因为我这里demo只是为了掩饰,imageView和控制器view约束尺寸一样了,会有放大效果,裁剪图片是正确的。

实现步骤

随着用户触摸移动,根据这个我们可以使用pan手势来实现,手势会有状态,我们这里可以记录开始触摸时的点,触摸中改变的点,触摸结束时的点。然后根据这些点,可以很容易的计算出我们需要裁剪的区域。

黑色透明区域,只是一个普通的,黑色透明的view,在用户移动手指时,动态计算截取区域并设置这个view的frame值。当松手的时候,裁剪图片并清除view的frame值即可。

代码实现

@IBOutlet weak var imageView: UIImageView!

private var startPoint = CGPointZero

override func viewDidLoad() {

super.viewDidLoad()

// 给当前控制器view添加一个pan手势

let panGesture = UIPanGestureRecognizer(target: self, action: #selector(didPan(_:)))

view.addGestureRecognizer(panGesture)

}

@objc private func didPan(pan: UIPanGestureRecognizer) {

let endPoint = pan.locationInView(view)

let clipRect = CGRect(origin: startPoint, size: CGSize(width: endPoint.x - startPoint.x, height: endPoint.y - startPoint.y))

if pan.state == .Began {

startPoint = pan.locationInView(view)

} else if pan.state == .Changed {

clipRectView.frame = clipRect

} else if pan.state == .Ended {

// 开启位图上下文,并裁剪指定区域

UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, 0)

let ctx = UIGraphicsGetCurrentContext()!

let rectPath = UIBezierPath(rect: clipRect)

rectPath.addClip()

imageView.layer.renderInContext(ctx)

let image = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

// 再次开启位图上下文,绘制裁剪后的图片

UIGraphicsBeginImageContextWithOptions(clipRect.size, false, 0)

image.drawAtPoint(CGPoint(x: -startPoint.x, y: -startPoint.y))

let newImage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

imageView.image = newImage

clipRectView.frame = CGRectZero

}

}

/// 裁剪区域黑色透明遮罩

private lazy var clipRectView: UIView = {

let clipRectView = UIView()

clipRectView.backgroundColor = UIColor(white: 0, alpha: 0.5)

self.view.addSubview(clipRectView)

return clipRectView

}()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

@IBOutletweakvarimageView:UIImageView!

privatevarstartPoint=CGPointZero

overridefuncviewDidLoad(){

super.viewDidLoad()

// 给当前控制器view添加一个pan手势

letpanGesture=UIPanGestureRecognizer(target:self,action:#selector(didPan(_:)))

view.addGestureRecognizer(panGesture)

}

@objcprivatefuncdidPan(pan:UIPanGestureRecognizer){

letendPoint=pan.locationInView(view)

letclipRect=CGRect(origin:startPoint,size:CGSize(width:endPoint.x-startPoint.x,height:endPoint.y-startPoint.y))

ifpan.state==.Began{

startPoint=pan.locationInView(view)

}elseifpan.state==.Changed{

clipRectView.frame=clipRect

}elseifpan.state==.Ended{

// 开启位图上下文,并裁剪指定区域

UIGraphicsBeginImageContextWithOptions(imageView.bounds.size,false,0)

letctx=UIGraphicsGetCurrentContext()!

letrectPath=UIBezierPath(rect:clipRect)

rectPath.addClip()

imageView.layer.renderInContext(ctx)

letimage=UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

// 再次开启位图上下文,绘制裁剪后的图片

UIGraphicsBeginImageContextWithOptions(clipRect.size,false,0)

image.drawAtPoint(CGPoint(x:-startPoint.x,y:-startPoint.y))

letnewImage=UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

imageView.image=newImage

clipRectView.frame=CGRectZero

}

}

/// 裁剪区域黑色透明遮罩

privatelazyvarclipRectView:UIView={

letclipRectView=UIView()

clipRectView.backgroundColor=UIColor(white:0,alpha:0.5)

self.view.addSubview(clipRectView)

returnclipRectView

}()

最终newImage就是我们需要的图片,demo下载:clipPhotoDemo

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值