您好,登錄后才能下訂單哦!
小編給大家分享一下IOS中如何實現照片編輯的view封裝,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
IOS 照片編輯的view封裝
該控件有旋轉,縮放,拖動,剪裁的功能,封裝成了一個ImageCropperView類
需要導入的庫:QuartzCore.framework
ImageCopperView.h
#import <UIKit/UIKit.h> @protocol ImageCropperDelegate; @interface ImageCropperView : UIView { UIImageView *imageView; id <ImageCropperDelegate> delegate; } @property (nonatomic, retain) UIImage *image; @property (nonatomic, retain) UIImage *croppedImage; @property (nonatomic, assign) id <ImageCropperDelegate> delegate; @property (nonatomic, assign) BOOL enable; @property (nonatomic, assign) BOOL isPaning; - (void)setup; - (void)finishCropping; - (void)reset; @end @protocol ImageCropperDelegate <NSObject> - (void)changeMoveStateWithCropper:(UIPanGestureRecognizer*)gesture Crop:(ImageCropperView*)imageCrop; @end
ImageCopperView.m
#import "ImageCropperView.h" #import <QuartzCore/QuartzCore.h> #include <math.h> #import "UIImage+Rotation.h" @interface ImageCropperView() { @private CGSize _originalImageViewSize; } @property (nonatomic, retain) UIImageView *imageView; @end @implementation ImageCropperView @synthesize imageView, image = _image, delegate, croppedImage; - (void)setup { _enable = YES; self.clipsToBounds = YES; self.backgroundColor = [UIColor clearColor]; self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.frame.size.width, self.frame.size.height)] autorelease]; imageView.userInteractionEnabled = YES; [self addSubview:imageView]; UIRotationGestureRecognizer *rotateGes = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateImage:)]; [imageView addGestureRecognizer:rotateGes]; [rotateGes release]; UIPinchGestureRecognizer *scaleGes = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleImage:)]; [imageView addGestureRecognizer:scaleGes]; [scaleGes release]; UIPanGestureRecognizer *moveGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveImage:)]; [moveGes setMinimumNumberOfTouches:1]; [moveGes setMaximumNumberOfTouches:1]; [imageView addGestureRecognizer:moveGes]; [moveGes release]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.frame = frame; [self setup]; } return self; } float _lastTransX = 0.0, _lastTransY = 0.0; - (void)moveImage:(UIPanGestureRecognizer *)sender { _isPaning = YES; if (delegate&&[delegate respondsToSelector:@selector(changeMoveStateWithCropper:Crop:)]) { [delegate changeMoveStateWithCropper:sender Crop:self]; }else{ return; } if (sender.numberOfTouches != 1||_enable == NO) { return; } //獲取在視圖中手勢的觸點位置 CGPoint translatedPoint = [sender translationInView:self]; if([sender state] == UIGestureRecognizerStateBegan) { _lastTransX = 0.0; _lastTransY = 0.0; } CGAffineTransform trans = CGAffineTransformMakeTranslation(translatedPoint.x - _lastTransX, translatedPoint.y - _lastTransY); //CGAffineTransformConcat將imageView.transform和trans兩個動畫連續起來 CGAffineTransform newTransform = CGAffineTransformConcat(imageView.transform, trans); _lastTransX = translatedPoint.x; _lastTransY = translatedPoint.y; NSLog(@"_lastTransX==%f,_lastTransY==%f",_lastTransX,_lastTransY); imageView.transform = newTransform; } float _lastScale = 1.0; - (void)scaleImage:(UIPinchGestureRecognizer *)sender { _isPaning = NO; if (sender.numberOfTouches != 2||_enable == NO) { return; } if([sender state] == UIGestureRecognizerStateBegan) { _lastScale = 1.0; return; } CGFloat scale = [sender scale]/_lastScale; CGAffineTransform currentTransform = imageView.transform; CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale); [imageView setTransform:newTransform]; _lastScale = [sender scale]; } float _lastRotation = 0.0; - (void)rotateImage:(UIRotationGestureRecognizer *)sender { _isPaning = NO; if (sender.numberOfTouches != 2||_enable == NO) { return; } if([sender state] == UIGestureRecognizerStateEnded) { _lastRotation = 0.0; return; } CGFloat rotation = -_lastRotation + [sender rotation]; CGAffineTransform currentTransform = imageView.transform; CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation); [imageView setTransform:newTransform]; _lastRotation = [sender rotation]; } - (void)setImage:(UIImage *)image { if (_image != image) { _image = [image retain]; } float _imageScale = self.frame.size.width / image.size.width; self.imageView.frame = CGRectMake(0, 0, image.size.width*_imageScale, image.size.height*_imageScale); _originalImageViewSize = CGSizeMake(image.size.width*_imageScale, image.size.height*_imageScale); imageView.image = image; imageView.center = CGPointMake(self.frame.size.width/2.0, self.frame.size.height/2.0); } - (void)finishCropping { float zoomScale = [[self.imageView.layer valueForKeyPath:@"transform.scale.x"] floatValue]; float rotate = [[self.imageView.layer valueForKeyPath:@"transform.rotation.z"] floatValue]; float _imageScale = _image.size.width/_originalImageViewSize.width; CGSize cropSize = CGSizeMake(self.frame.size.width/zoomScale, self.frame.size.height/zoomScale); CGPoint cropperViewOrigin = CGPointMake((0.0 - self.imageView.frame.origin.x)/zoomScale, (0.0 - self.imageView.frame.origin.y)/zoomScale); if((NSInteger)cropSize.width % 2 == 1) { cropSize.width = ceil(cropSize.width); } if((NSInteger)cropSize.height % 2 == 1) { cropSize.height = ceil(cropSize.height); } CGRect CropRectinImage = CGRectMake((NSInteger)(cropperViewOrigin.x*_imageScale) ,(NSInteger)( cropperViewOrigin.y*_imageScale), (NSInteger)(cropSize.width*_imageScale),(NSInteger)(cropSize.height*_imageScale)); UIImage *rotInputImage = [self.image imageRotatedByRadians:rotate]; CGImageRef tmp = CGImageCreateWithImageInRect([rotInputImage CGImage], CropRectinImage); self.croppedImage = [UIImage imageWithCGImage:tmp scale:self.image.scale orientation:self.image.imageOrientation]; CGImageRelease(tmp); } - (void)reset { self.imageView.transform = CGAffineTransformIdentity; } - (void)dealloc { self.image = nil; self.croppedImage = nil; self.imageView = nil; [super dealloc]; } @end
對UIImage添加了一個category
UIImage+Rotation.h
#import <UIKit/UIKit.h> @interface UIImage (Rotation) - (UIImage *)imageRotatedByRadians:(CGFloat)radians; - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees; @end
UIImage+Rotation.m
#import "UIImage+Rotation.h" /************ 角度=弧度/Pi*180 弧度=角度/180*Pi *************/ CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}; CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;}; @implementation UIImage (Rotation) - (UIImage *)imageRotatedByRadians:(CGFloat)radians { return [self imageRotatedByDegrees:RadiansToDegrees(radians)]; } - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees { /***** CGAffineTransformMakeRotation 通過指定角度來創建一個旋轉矩陣 CGAffineTransformRotate 在已存在的矩陣中使用旋轉 *****/ UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)]; CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees)); //給view旋轉角度 rotatedViewBox.transform = t; CGSize rotatedSize = rotatedViewBox.frame.size; [rotatedViewBox release]; //開始編輯圖形上下文 UIGraphicsBeginImageContext(rotatedSize); //定義一個圖形上下文 CGContextRef bitmap = UIGraphicsGetCurrentContext(); //沿x軸移動rotatedSize.width/2,y軸移動rotatedSize.height CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2); //以原點(左下角)為中心旋轉DegreesToRadians(degrees)弧度,正角度逆時針,負角度順時針 CGContextRotateCTM(bitmap, DegreesToRadians(degrees)); //縮放x軸,y軸方向 CGContextScaleCTM(bitmap, 1.0, -1.0); //繪制位圖 CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]); //賦值給UIImage UIImage *resImage = UIGraphicsGetImageFromCurrentImageContext(); //結束繪制 UIGraphicsEndImageContext(); return resImage; } @end;
ViewController.m
#import "ViewController.h" #import <QuartzCore/QuartzCore.h> #import "ImagecropperView.h" @interface ViewController ()<ImageCropperDelegate>{ } @property (nonatomic, retain) IBOutlet ImageCropperView *cropper; @property (nonatomic, retain) IBOutlet UIImageView *result; @property (retain, nonatomic) IBOutlet UIImageView *resultSecond; @property (nonatomic, retain) IBOutlet UIButton *btn; @property (retain, nonatomic) IBOutlet ImageCropperView *cropperSecond; @property (retain, nonatomic) IBOutlet UIButton *cropButton; @end @implementation ViewController //@synthesize cropper, result, btn; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. _cropper.layer.borderWidth = 1.0; _cropper.layer.borderColor = [UIColor blueColor].CGColor; _cropper.delegate = self; [_cropper setup]; _cropper.image = [UIImage imageNamed:@"2.jpg"]; [_btn addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside]; _cropperSecond.layer.borderColor = [UIColor blackColor].CGColor; _cropperSecond.layer.borderWidth = 2.0; _cropperSecond.delegate = self; [_cropperSecond setup]; _cropperSecond.image = [UIImage imageNamed:@"1.jpg"]; [_cropButton addTarget:self action:@selector(tapCropButton) forControlEvents:UIControlEventTouchUpInside]; } - (void)buttonClicked { if ([_btn.currentTitle isEqualToString:@"Crop1"]) { [_cropper finishCropping];//保存 _result.image = _cropper.croppedImage; _cropper.hidden = YES; [_btn setTitle:@"Back" forState:UIControlStateNormal]; [_btn setTitle:@"Back" forState:UIControlStateHighlighted]; }else { [_cropper reset]; _cropper.hidden = NO; [_btn setTitle:@"Crop1" forState:UIControlStateNormal]; [_btn setTitle:@"Crop1" forState:UIControlStateHighlighted]; _result.image = nil; } _cropperSecond.enable = YES; _cropper.enable = YES; } - (void)tapCropButton{ if ([_cropButton.currentTitle isEqualToString:@"Crop2"]) { [_cropperSecond finishCropping]; _cropperSecond.enable = NO; _resultSecond.image = _cropperSecond.croppedImage; _cropperSecond.hidden = YES; [_cropButton setTitle:@"Back" forState:UIControlStateNormal]; [_cropButton setTitle:@"Back" forState:UIControlStateHighlighted]; }else { [_cropperSecond reset]; _cropperSecond.hidden = NO; [_cropButton setTitle:@"Crop2" forState:UIControlStateNormal]; [_cropButton setTitle:@"Crop2" forState:UIControlStateHighlighted]; _resultSecond.image = nil; } _cropperSecond.enable = YES; _cropper.enable = YES; } #pragma mark - ImageCropperDelegate - (void)changeMoveStateWithCropper:(UIPanGestureRecognizer*)gesture Crop:(ImageCropperView*)imageCrop{ if (gesture.state == UIGestureRecognizerStateEnded) { NSLog(@"點擊編輯器結束,兩個_cropper都可以進行編輯"); _cropperSecond.enable = YES; _cropper.enable = YES; } } - (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event; { //判斷點擊在控件上 UITouch *touch = [touches anyObject]; if ([_cropper pointInside:[touch locationInView:_cropper] withEvent:nil]) { NSLog(@"_cropper1 被觸摸,禁用_cropper2"); _cropperSecond.enable = NO; }else if ([_cropperSecond pointInside:[touch locationInView:_cropperSecond] withEvent:nil]){ NSLog(@"_cropper2 被觸摸,禁用_cropper1"); _cropper.enable = NO; } } - (void)dealloc { [_cropperSecond release]; [_cropButton release]; [_resultSecond release]; [super dealloc]; } - (void)viewDidUnload { [self setCropperSecond:nil]; [self setCropButton:nil]; [self setResultSecond:nil]; [super viewDidUnload]; } @end
截圖:
最后要注意,因為我是用xib做的,拖上去的UIView要將其Class改成ImageCropperView
看完了這篇文章,相信你對“IOS中如何實現照片編輯的view封裝”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。