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

下面是截图

ios 照片编辑的view封装

最后要注意,因为我是用xib做的,拖上去的UIView要将其Class改成ImageCropperView

你可能感兴趣的:(view)