No Description

FKPhotoClipView.m 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. //
  2. // FKPhotoClipView.m
  3. // FirstLink
  4. //
  5. // Created by ascii on 16/6/13.
  6. // Copyright © 2016年 FirstLink. All rights reserved.
  7. //
  8. #import "FKPhotoClipView.h"
  9. @implementation FKPhotoClipGridView
  10. - (id)init {
  11. self = [super init];
  12. if (self) {
  13. [self configInitData];
  14. self.layer.borderWidth = self.width;
  15. self.layer.borderColor = self.color.CGColor;
  16. }
  17. return self;
  18. }
  19. - (id)initWithFrame:(CGRect)frame {
  20. self = [super initWithFrame:frame];
  21. if (self) {
  22. [self configInitData];
  23. }
  24. return self;
  25. }
  26. - (void)configInitData {
  27. self.color = [UIColor whiteColor];
  28. self.width = 1;
  29. self.row = 2;
  30. self.column = 2;
  31. }
  32. - (void)drawRect:(CGRect)rect {
  33. [super drawRect:rect];
  34. CGContextRef context = UIGraphicsGetCurrentContext();
  35. CGContextSetStrokeColorWithColor(context, self.color.CGColor);
  36. CGContextSetLineWidth(context, self.width);
  37. // draw row line
  38. int distance = (int)(CGRectGetHeight(self.frame)/((float)(self.row + 1)));
  39. for (int idx = 0; idx < self.row; idx++) {
  40. CGContextMoveToPoint(context, 0.0f, distance*(idx+1));
  41. CGContextAddLineToPoint(context, CGRectGetWidth(self.frame), distance*(idx+1));
  42. }
  43. // draw column line
  44. distance = (int)(CGRectGetWidth(self.frame)/((float)(self.column + 1)));
  45. for (int idx = 0; idx < self.column; idx++) {
  46. CGContextMoveToPoint(context, distance*(idx+1), 0.0f);
  47. CGContextAddLineToPoint(context, distance*(idx+1), CGRectGetHeight(self.frame));
  48. }
  49. CGContextStrokePath(context);
  50. }
  51. @end
  52. #pragma mark - FKPhotoClipView
  53. @interface FKPhotoClipView ()
  54. @property (nonatomic, strong) UIImage *sourceImage;
  55. @property (nonatomic, strong) UIScrollView *scrollView;
  56. @property (nonatomic, strong) UIImageView *imageView;
  57. @property (nonatomic, strong) FKPhotoClipGridView *gridView;
  58. @end
  59. @implementation FKPhotoClipView
  60. /*
  61. // Only override drawRect: if you perform custom drawing.
  62. // An empty implementation adversely affects performance during animation.
  63. - (void)drawRect:(CGRect)rect {
  64. // Drawing code
  65. }
  66. */
  67. - (instancetype)initWithImage:(UIImage *)image {
  68. self = [super init];
  69. if (self) {
  70. [self setImage:image];
  71. self.clipsToBounds = YES;
  72. [self addSubview:self.scrollView];
  73. [self.scrollView addSubview:self.imageView];
  74. [self addSubview:self.gridView];
  75. }
  76. return self;
  77. }
  78. - (void)setImage:(UIImage *)image {
  79. _sourceImage = [image copy];
  80. self.imageView.image = _sourceImage;
  81. }
  82. - (UIImage *)getClipImage {
  83. CGRect rectInImageView = CGRectMake(self.scrollView.contentOffset.x
  84. , self.scrollView.contentOffset.y
  85. , CGRectGetWidth(self.gridView.frame)
  86. , CGRectGetHeight(self.gridView.frame));
  87. CGFloat scale = CGRectGetWidth(self.imageView.frame)/self.sourceImage.size.width;
  88. CGRect rectInImage = CGRectMake((int)(CGRectGetMinX(rectInImageView)/scale)
  89. , (int)(CGRectGetMinY(rectInImageView)/scale)
  90. , (int)(CGRectGetWidth(rectInImageView)/scale)
  91. , (int)(CGRectGetHeight(rectInImageView)/scale));
  92. CGImageRef suourceImageRef = CGImageCreateWithImageInRect(self.sourceImage.CGImage, rectInImage);
  93. CGRect subBounds = CGRectMake(0, 0, CGImageGetWidth(suourceImageRef), CGImageGetHeight(suourceImageRef));
  94. UIGraphicsBeginImageContext(subBounds.size);
  95. CGContextRef context = UIGraphicsGetCurrentContext();
  96. CGContextDrawImage(context, subBounds, suourceImageRef);
  97. UIImage* subImage = [UIImage imageWithCGImage:suourceImageRef];
  98. UIGraphicsEndImageContext();
  99. return subImage;
  100. }
  101. - (void)drawRect:(CGRect)rect {
  102. [super drawRect:rect];
  103. if (self.sourceImage) {
  104. self.gridView.frame = self.bounds;
  105. self.scrollView.frame = self.bounds;
  106. [self setVisableViewContentSize:[self minVisableViewSize]];
  107. [self setVisableViewCenterAnimated:NO];
  108. }
  109. }
  110. #pragma mark - Method
  111. - (CGSize)minVisableViewSize {
  112. CGFloat length = CGRectGetWidth(self.frame);
  113. CGFloat width = self.sourceImage.size.width;
  114. CGFloat height = self.sourceImage.size.height;
  115. CGFloat minSide = MIN(width, height);
  116. return CGSizeMake(ceilf(width*length/minSide), ceilf(height*length/minSide));
  117. }
  118. - (void)setVisableViewContentSize:(CGSize)size {
  119. // +1是为了保证scrollView可滑动
  120. self.scrollView.contentSize = size;
  121. self.imageView.frame = CGRectMake(0, 0, size.width + 1, size.height + 1);
  122. }
  123. - (void)scaleVisableViewToMinSize:(CGSize)size {
  124. CGSize minSize = [self minVisableViewSize];
  125. if (size.width < minSize.width || size.height < minSize.height) {
  126. __weak FKPhotoClipView *weakSelf = self;
  127. [UIView animateWithDuration:0.3
  128. animations:^
  129. {
  130. // +1是为了保证scrollView可滑动
  131. weakSelf.scrollView.contentSize = minSize;
  132. weakSelf.imageView.frame = CGRectMake(0, 0, minSize.width + 1, minSize.height + 1);
  133. } completion:^(BOOL finished)
  134. {
  135. [weakSelf setVisableViewCenterAnimated:NO];
  136. }];
  137. }
  138. }
  139. - (void)setVisableViewCenterAnimated:(BOOL)animated {
  140. CGFloat centerOffsetX = (self.scrollView.contentSize.width/2) - (self.scrollView.bounds.size.width/2);
  141. CGFloat centerOffsetY = (self.scrollView.contentSize.height/2) - (self.scrollView.bounds.size.width/2);
  142. [self.scrollView setContentOffset:CGPointMake(centerOffsetX, centerOffsetY) animated:animated];
  143. }
  144. - (void)setVisableViewContentOffsetScale:(CGFloat)scale {
  145. CGFloat centerOffsetX = (self.scrollView.contentOffset.x*scale);
  146. CGFloat centerOffsetY = (self.scrollView.contentOffset.y*scale);
  147. [self.scrollView setContentOffset:CGPointMake(centerOffsetX, centerOffsetY) animated:NO];
  148. }
  149. #pragma mark - Action
  150. - (void)pinchViewGesture:(UIPinchGestureRecognizer *)pinchGestureRecognizer {
  151. if (pinchGestureRecognizer.state == UIGestureRecognizerStateBegan || pinchGestureRecognizer.state == UIGestureRecognizerStateChanged || pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) {
  152. UIView *view = self.imageView;
  153. CGFloat scale = pinchGestureRecognizer.scale;
  154. view.transform = CGAffineTransformScale(view.transform, scale, scale);
  155. pinchGestureRecognizer.scale = 1;
  156. if (pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) {
  157. [self scaleVisableViewToMinSize:view.frame.size];
  158. } else {
  159. [self setVisableViewContentSize:view.frame.size];
  160. [self setVisableViewContentOffsetScale:scale];
  161. }
  162. }
  163. }
  164. #pragma mark - Property
  165. - (UIScrollView *)scrollView{
  166. if (!_scrollView) {
  167. _scrollView = [[UIScrollView alloc] init];
  168. _scrollView.backgroundColor = [UIColor blackColor];
  169. _scrollView.showsHorizontalScrollIndicator = NO;
  170. _scrollView.showsVerticalScrollIndicator = NO;
  171. }
  172. return _scrollView;
  173. }
  174. - (UIImageView *)imageView {
  175. if (!_imageView) {
  176. _imageView = [UIImageView new];
  177. _imageView.userInteractionEnabled = YES;
  178. UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchViewGesture:)];
  179. [_imageView addGestureRecognizer:gesture];
  180. }
  181. return _imageView;
  182. }
  183. - (FKPhotoClipGridView *)gridView {
  184. if (!_gridView) {
  185. _gridView = [FKPhotoClipGridView new];
  186. _gridView.userInteractionEnabled = NO;
  187. _gridView.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
  188. }
  189. return _gridView;
  190. }
  191. @end