이미지 자르기 + 제스쳐 + transparentview 예제
이미지 자르기 + 제스쳐 + transparentview 예제
#import <UIKit/UIKit.h>
#import "ImageViewerViewController.h"
@interface ViewController : UIViewController
- (IBAction)captureBtnAction:(id)sender;
@end
#import "ViewController.h"
@interface ViewController (){
IBOutlet UIImageView *myImage;
UIView *testVw; //뷰파인더
CGPoint prevPoint; //옮기기 전 위치 point
UIView *resizeVw; //빨간색
UIView *resizeVw2;// 파란색
UIBezierPath *backPath; //검은색 bulr
UIBezierPath *framePath; //포커스
CAShapeLayer *fillLayer;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//myImage.frame = self.view.frame;
backPath = [UIBezierPath bezierPathWithRect:self.view.frame];
//뷰 파인터
testVw = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100,100)];
testVw.backgroundColor = [UIColor clearColor];
testVw.center = self.view.center;
testVw.layer.borderColor = [UIColor lightGrayColor].CGColor;
testVw.layer.borderWidth = 1.0f;
[self.view addSubview:testVw];
//포커스
framePath = [UIBezierPath bezierPathWithRect:testVw.frame];
[backPath appendPath:framePath];
backPath.usesEvenOddFillRule = YES;
//오버레이뷰
fillLayer = [CAShapeLayer layer];
fillLayer.path = backPath.CGPath;
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.fillColor = [UIColor blackColor].CGColor;
fillLayer.opacity = 0.4;
//루트뷰 레이어에 오버레이뷰 추가
[self.view.layer addSublayer:fillLayer];
UIPanGestureRecognizer *panResizeGestureTestVw = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(resizeTranslateTestVw:)];
[testVw addGestureRecognizer:panResizeGestureTestVw];
//사이즈 조절할 빨간색 네모 -1
resizeVw = [[UIView alloc]initWithFrame:CGRectMake(testVw.frame.size.width - 25, testVw.frame.size.height -25, 25, 25)];
resizeVw.backgroundColor = [UIColor clearColor];
[testVw addSubview:resizeVw];
//제스쳐 이벤트 추가
UIPanGestureRecognizer *panResizeGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(resizeTranslate:)];
[resizeVw addGestureRecognizer:panResizeGesture];
//사이즈 조절할 파란색 네모 -2
resizeVw2 = [[UIView alloc]initWithFrame:CGRectMake( testVw.frame.size.width -100, testVw.frame.size.height-100, 25, 25)];
resizeVw2.backgroundColor = [UIColor clearColor];
[testVw addSubview:resizeVw2];
//제스쳐 이벤트 추가
UIPanGestureRecognizer *panResizeGesture2 = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(resizeTranslate2:)];
[resizeVw2 addGestureRecognizer:panResizeGesture2];
}
//파인더 뷰 드래그
-(void)resizeTranslateTestVw:(UIPanGestureRecognizer *) recognizer{
if ([recognizer state] == UIGestureRecognizerStateBegan) {
NSLog(@" TestVw 제스쳐 시작");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
}else if ([recognizer state] == UIGestureRecognizerStateChanged){
NSLog(@" TestVw 제스쳐 작동중");
CGPoint newPoint = [recognizer locationInView:testVw.superview]; //이동한 후 위치값
NSLog(@"testVw.bounds.origin x : %f , testVw.bounds.origin : %f" ,testVw.bounds.origin.x , testVw.bounds.origin.y);
NSLog(@"newPoint x : %f , y : %f" ,newPoint.x , newPoint.y);
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y);
//드래그 된 testVw 다시 위치 설정
testVw.center = [recognizer locationInView:testVw.superview];
//뷰파인더 셋팅
[self setTransParentViewFinderSetting];
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
}else if ([recognizer state] == UIGestureRecognizerStateEnded){
NSLog(@"TestVw 제스쳐 끝");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
}
}
//초록색 버튼 사이즈 조절2
-(void)resizeTranslate2:(UIPanGestureRecognizer *) recognizer{
if ([recognizer state] == UIGestureRecognizerStateBegan) {
NSLog(@"제스쳐 시작");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y);
NSLog(@"testVw.bounds.size.width : %f , testVw.bounds.size.heigth : %f " ,
testVw.bounds.size.width, testVw.bounds.size.height);
NSLog(@"testVw.frame.size.width : %f , testVw.frame.size.heigth : %f " ,
testVw.frame.size.width, testVw.frame.size.height);
}else if ([recognizer state] == UIGestureRecognizerStateChanged){
if (testVw.bounds.size.width < 100) {
NSLog(@"testVw.bounds.size.width가 100 보다 작습니다.");
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, 100, testVw.bounds.size.height);
resizeVw2.frame = CGRectMake(testVw.frame.size.width -100, testVw.frame.size.height-100, 25, 25);
}
if (testVw.bounds.size.height < 100) {
NSLog(@"testVw.bounds.size.height가 100 보다 작습니다.");
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, testVw.bounds.size.width, 100);
resizeVw2.frame = CGRectMake(testVw.frame.size.width -100, testVw.frame.size.height-100, 25, 25);
}
NSLog(@"testVw.bounds.size.height가 100 보다 큽니다!");
//제스쳐 객체는 testVw.superview, 즉 self.view에서 인식하고 해당 위치(x,y)값을 리턴한다.
CGPoint newPoint = [recognizer locationInView:testVw.superview]; //이동한 후 위치값
float wChange = 0.0 , hChange = 0.0; //원래 자리에서 이동한 위치값을 뺀 변경된값
NSLog(@"point x : %f , y : %f" ,newPoint.x , newPoint.y); //이동된 위치
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y); //원래자리 값
wChange = (newPoint.x - prevPoint.x); //이동된 위치값 - 원래자리값 = 변경된값
hChange = (newPoint.y - prevPoint.y);
NSLog(@"wChange : %f , hChange : %f" ,wChange , hChange);
//드래그 된 testVw 다시 위치 설정
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, testVw.bounds.size.width - (wChange), testVw.bounds.size.height - (hChange));
//뷰파인더 위치 및 크기 재설정
[self setTransParentViewFinderSetting];
//조절버튼 위치 재설정
resizeVw2.frame = CGRectMake(0, 0, 25, 25);
resizeVw.frame = CGRectMake(testVw.bounds.size.width - 25, testVw.bounds.size.height - 25, 25, 25);
NSLog(@"testVw.bounds : %@",NSStringFromCGRect(testVw.bounds));
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
}else if ([recognizer state] == UIGestureRecognizerStateEnded){
NSLog(@"제스쳐 끝");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y);
NSLog(@"testVw.bounds.size.width : %f , testVw.bounds.size.heigth : %f " , testVw.bounds.size.width, testVw.bounds.size.height);
NSLog(@"testVw.frame.size.width : %f , testVw.frame.size.heigth : %f " , testVw.frame.size.width, testVw.frame.size.height);
NSLog(@"얼마나 이동했나요 : %@" , NSStringFromCGPoint([recognizer translationInView:testVw.superview]) );
}
}
//사이즈 조절1
-(void)resizeTranslate:(UIPanGestureRecognizer *) recognizer{
if ([recognizer state] == UIGestureRecognizerStateBegan) {
NSLog(@"제스쳐 시작");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y);
NSLog(@"testVw.bounds.size.width : %f , testVw.bounds.size.heigth : %f " ,
testVw.bounds.size.width, testVw.bounds.size.height);
NSLog(@"testVw.frame.size.width : %f , testVw.frame.size.heigth : %f " ,
testVw.frame.size.width, testVw.frame.size.height);
}else if ([recognizer state] == UIGestureRecognizerStateChanged){
if (testVw.bounds.size.width < 100) {
NSLog(@"testVw.bounds.size.width가 100 보다 작습니다.");
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, 100, testVw.bounds.size.height);
resizeVw.frame = CGRectMake(testVw.bounds.size.width - 25, testVw.bounds.size.height - 25, 25, 25);
}
if (testVw.bounds.size.height < 100) {
NSLog(@"testVw.bounds.size.height가 100 보다 작습니다.");
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, testVw.bounds.size.width, 100);
resizeVw.frame = CGRectMake(testVw.bounds.size.width - 25, testVw.bounds.size.height - 25, 25, 25);
}
NSLog(@"testVw.bounds.size.height가 100 보다 큽니다!");
//제스쳐 객체는 testVw.superview, 즉 self.view에서 인식하고 해당 위치(x,y)값을 리턴한다.
CGPoint newPoint = [recognizer locationInView:testVw.superview]; //이동한 후 위치값
float wChange = 0.0 , hChange = 0.0; //원래 자리에서 이동한 위치값을 뺀 변경된값
NSLog(@"point x : %f , y : %f" ,newPoint.x , newPoint.y); //이동된 위치
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y); //원래자리 값
wChange = (newPoint.x - prevPoint.x); //이동된 위치값 - 원래자리값 = 변경된값
hChange = (newPoint.y - prevPoint.y);
NSLog(@"wChange : %f , hChange : %f" ,wChange , hChange);
//드래그 된 testVw 다시 위치 설정
testVw.bounds = CGRectMake(testVw.bounds.origin.x, testVw.bounds.origin.y, testVw.bounds.size.width + (wChange), testVw.bounds.size.height + (hChange));
//뷰파인더 위치 및 크기 재설정
[self setTransParentViewFinderSetting];
resizeVw.frame = CGRectMake(testVw.bounds.size.width - 25, testVw.bounds.size.height - 25, 25, 25);
NSLog(@"testVw.bounds : %@",NSStringFromCGRect(testVw.bounds));
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
}else if ([recognizer state] == UIGestureRecognizerStateEnded){
NSLog(@"제스쳐 끝");
prevPoint = [recognizer locationInView:testVw.superview];
[testVw setNeedsDisplay];
NSLog(@"prevPoint x : %f , y : %f" ,prevPoint.x , prevPoint.y);
NSLog(@"testVw.bounds.size.width : %f , testVw.bounds.size.heigth : %f " , testVw.bounds.size.width, testVw.bounds.size.height);
NSLog(@"testVw.frame.size.width : %f , testVw.frame.size.heigth : %f " , testVw.frame.size.width, testVw.frame.size.height);
NSLog(@"얼마나 이동했나요 : %@" , NSStringFromCGPoint([recognizer translationInView:testVw.superview]) );
}
}
//뷰파인더 위치 설정을 위한 메소드
-(void)setTransParentViewFinderSetting{
//바탕화면 검은색 위치와 바탕화면 색깔 해제
[backPath removeAllPoints];
[fillLayer removeFromSuperlayer];
//검은색 바탕화면 다시 셋팅
backPath = [UIBezierPath bezierPathWithRect:self.view.frame];
//드래그된 testVw 위치를 framepath(파인터뷰에 대입)
framePath = [UIBezierPath bezierPathWithRect:testVw.frame];
//바탕화면 검은색 위치 안에 파인어뷰 위치 대입
[backPath appendPath:framePath];
backPath.usesEvenOddFillRule = YES;
//오버레이뷰 = 백그라운드
fillLayer = [CAShapeLayer layer];
fillLayer.path = backPath.CGPath;
fillLayer.fillRule = kCAFillRuleEvenOdd;
fillLayer.fillColor = [UIColor blackColor].CGColor;
fillLayer.opacity = 0.4;
//루트뷰 레이어에 오버레이뷰 추가
[self.view.layer addSublayer:fillLayer];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)captureBtnAction:(id)sender {
NSLog(@"captureBtnAction : %@" , NSStringFromCGRect(CGRectMake(testVw.frame.origin.x, testVw.frame.origin.y , testVw.frame.size.width, testVw.frame.size.height)));
UIImage *croppedImg = nil;
CGRect cropRect =CGRectMake(testVw.frame.origin.x - 6.5, testVw.frame.origin.y - 76.5
, testVw.bounds.size.width-4.5, testVw.bounds.size.height-6.5);
//CGRect cropRect =CGRectMake(110,110,100,100);
croppedImg = [self croppIngimageByImageName:myImage.image toRect:cropRect];
ImageViewerViewController *imageVC = [[ImageViewerViewController alloc]init];
imageVC.cropedimage = croppedImg;
[self presentViewController:imageVC animated:YES completion:nil];
}
- (UIImage *)croppIngimageByImageName:(UIImage *)imageToCrop toRect:(CGRect)rect
{
//CGRect CropRect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height+50);
CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return cropped;
}
@end
자른이미지 보여주는 컨트롤러
#import <UIKit/UIKit.h>
@interface ImageViewerViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIImageView *myImageView;
- (IBAction)backBtnAction:(id)sender;
@property(strong,nonatomic) UIImage *cropedimage;
@end
#import "ImageViewerViewController.h"
@interface ImageViewerViewController ()
@end
@implementation ImageViewerViewController
- (void)viewDidLoad {
[super viewDidLoad];
if (_myImageView != nil) {
self.myImageView.image = _cropedimage;
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)backBtnAction:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
self.myImageView.image = nil;
}];
}
@end