Skip to content

Commit

Permalink
better crop image quality, this should fix issue #11and #7 for Custom…
Browse files Browse the repository at this point in the history
… Crop
  • Loading branch information
gekitz committed Mar 4, 2013
1 parent 50df2c3 commit 2a91f31
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 12 deletions.
66 changes: 56 additions & 10 deletions GKClasses/GKImageCropView.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@

#import <QuartzCore/QuartzCore.h>

#define rad(angle) ((angle) / 180.0 * M_PI)

static CGRect GKScaleRect(CGRect rect, CGFloat scale)
{
return CGRectMake(rect.origin.x * scale, rect.origin.y * scale, rect.size.width * scale, rect.size.height * scale);
}

@interface ScrollView : UIScrollView
@end

Expand Down Expand Up @@ -48,6 +55,8 @@ @interface GKImageCropView ()<UIScrollViewDelegate>
@property (nonatomic, strong) GKImageCropOverlayView *cropOverlayView;
@property (nonatomic, assign) CGFloat xOffset;
@property (nonatomic, assign) CGFloat yOffset;

- (CGAffineTransform)_orientationTransformedRectOfImage:(UIImage *)image;
@end

@implementation GKImageCropView
Expand Down Expand Up @@ -96,18 +105,55 @@ - (UIImage *)croppedImage{
CGFloat xPositionInScrollView = resizeableView.contentView.frame.origin.x + self.scrollView.contentOffset.x - self.xOffset;
CGFloat yPositionInScrollView = resizeableView.contentView.frame.origin.y + self.scrollView.contentOffset.y - self.yOffset;
CGContextTranslateCTM(ctx, -(xPositionInScrollView), -(yPositionInScrollView));

[self.scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
else {

CGFloat scale = self.scrollView.maximumZoomScale / self.scrollView.zoomScale;
UIGraphicsBeginImageContextWithOptions(self.scrollView.frame.size, self.scrollView.opaque, scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -self.scrollView.contentOffset.x, -self.scrollView.contentOffset.y);
//scaled width/height in regards of real width to crop width
CGFloat scaleWidth = self.imageToCrop.size.width / self.cropSize.width;
CGFloat scaleHeight = self.imageToCrop.size.height / self.cropSize.height;
CGFloat scale = MAX(scaleWidth, scaleHeight);

//extract visible rect from scrollview and scale it
CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:imageView];
visibleRect = GKScaleRect(visibleRect, scale);

//transform visible rect to image orientation
CGAffineTransform rectTransform = [self _orientationTransformedRectOfImage:self.imageToCrop];
visibleRect = CGRectApplyAffineTransform(visibleRect, rectTransform);

//finally crop image
CGImageRef imageRef = CGImageCreateWithImageInRect([self.imageToCrop CGImage], visibleRect);
UIImage *result = [UIImage imageWithCGImage:imageRef scale:self.imageToCrop.scale orientation:self.imageToCrop.imageOrientation];
CGImageRelease(imageRef);

return result;
}
[self.scrollView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}

- (CGAffineTransform)_orientationTransformedRectOfImage:(UIImage *)img
{
CGAffineTransform rectTransform;
switch (img.imageOrientation)
{
case UIImageOrientationLeft:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(90)), 0, -img.size.height);
break;
case UIImageOrientationRight:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-90)), -img.size.width, 0);
break;
case UIImageOrientationDown:
rectTransform = CGAffineTransformTranslate(CGAffineTransformMakeRotation(rad(-180)), -img.size.width, -img.size.height);
break;
default:
rectTransform = CGAffineTransformIdentity;
};

return CGAffineTransformScale(rectTransform, img.scale, img.scale);
}

#pragma mark -
Expand All @@ -126,12 +172,12 @@ - (id)initWithFrame:(CGRect)frame
self.scrollView.delegate = self;
self.scrollView.clipsToBounds = NO;
self.scrollView.decelerationRate = 0.0;
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.backgroundColor = [UIColor greenColor];
[self addSubview:self.scrollView];

self.imageView = [[UIImageView alloc] initWithFrame:self.scrollView.frame];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.backgroundColor = [UIColor blackColor];
self.imageView.backgroundColor = [UIColor greenColor];
[self.scrollView addSubview:self.imageView];


Expand Down
4 changes: 2 additions & 2 deletions GKImagePicker/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ @implementation ViewController
- (void)showPicker:(UIButton *)btn{

self.imagePicker = [[GKImagePicker alloc] init];
self.imagePicker.cropSize = CGSizeMake(320, 320);
self.imagePicker.cropSize = CGSizeMake(280, 280);
self.imagePicker.delegate = self;

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
Expand Down Expand Up @@ -95,7 +95,7 @@ - (void)viewDidLoad
[self.view addSubview:self.customCropButton];

self.normalCropButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.normalCropButton setTitle:@"Normal Crop" forState:UIControlStateNormal];
[self.normalCropButton setTitle:@"Apple's Build In Crop" forState:UIControlStateNormal];
[self.normalCropButton addTarget:self action:@selector(showNormalPicker:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.normalCropButton];

Expand Down

0 comments on commit 2a91f31

Please sign in to comment.