打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
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

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
UIView Tutorial for iOS: How To Make a Custom UIView in iOS 5
ios通过按钮点击异步加载图片
iOS开发多线程之队列组----下载合并图片
iOS开发之画图板(贝塞尔曲线)
iOS简易无限滚动的图片轮播器Demo事例
iOS开发之详解剪贴板
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服