当原始图像尺寸小于特定裁剪类视图(300,300)并且用户在那时缩放该时间裁剪图像变得不精确(300,300)时,裁剪图像出现问题。在下面我添加了代码:
#import "CropImage.h"
#define kMaxZoomScale 15 // Edited 3.0
#define kMinimumZoomScale 0.5
@implementation CropImage
{
UIImageView *imgView;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
// IMAGEVIEW main
CGRect imgFrame = CGRectMake(0,0,300,300); // inital size
imgView = [[UIImageView alloc]initWithFrame:imgFrame] ;
[imgView setAutoresizesSubviews:NO];
[imgView setUserInteractionEnabled:NO];
[imgView setBackgroundColor:[UIColor clearColor]];
[imgView setContentMode:UIViewContentModeScaleAspectFit];
[imgView setClipsToBounds:YES]; // Edited
[self addSubview:imgView];
[self setScrollEnabled:YES];
[self setDelegate:self];
[self setUserInteractionEnabled:YES];
[self setAutoresizesSubviews:YES];
[self setBounces:YES];
self.minimumZoomScale = kMinimumZoomScale;
self.maximumZoomScale = kMaxZoomScale;
}
return self;
}
-(void)setImageForCrop:(UIImage *)image
{
[imgView setImage:image];
CGSize sizeCal;
if (image.size.height > imgView.frame.size.height || image.size.width > imgView.frame.size.width) {
sizeCal = [self getCGSizeAspectFitRatio:image.size withBoundImageSize:imgView.frame.size];
}
else
{
sizeCal = [self getCGSizeAspectFitRatio:image.size withBoundImageSize:image.size];
}
float x = ((self.frame.size.width/2)-(sizeCal.width/2));
float y = ((self.frame.size.height/2)-(sizeCal.height/2));
[imgView setFrame:CGRectMake(x, y, sizeCal.width,sizeCal.height)];
[self setContentSize:imgView.frame.size];
}
#pragma mark
#pragma mark - CGSIZE UTILITY
-(CGSize) getCGSizeAspectFitRatio:(CGSize) aspectRatio withBoundImageSize:(CGSize)boundingSize
{
float mW = boundingSize.width / aspectRatio.width;
float mH = boundingSize.height / aspectRatio.height;
if( mH < mW )
boundingSize.width = boundingSize.height / aspectRatio.height * aspectRatio.width;
else if( mW < mH )
boundingSize.height = boundingSize.width / aspectRatio.width * aspectRatio.height;
return boundingSize;
}
#pragma mark SCROLL VIEW DELEGATE
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
}
//return a view that will be scaled.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imgView;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
[self centerScrollViewContents:scrollView];
}
- (void)centerScrollViewContents:(UIScrollView *)scrollView
{
@try
{
CGSize boundsSize = self.bounds.size;
CGRect contentsFrame = imgView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
}
else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
}
else {
contentsFrame.origin.y = 0.0f;
}
imgView.frame = contentsFrame;
//This logic is for smaller images with size < scrollview size
UIView *subView = [scrollView.subviews objectAtIndex:0];
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
(scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
subView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
scrollView.contentSize.height * 0.5 + offsetY);
}
@catch (NSException *exception)
{
NSLog(@"centerScrollViewContents %@",exception);
}
@finally
{
}
}
#pragma mark
#pragma mark - CROP IMAGE
-(UIImage *)getCropImage
{
if (imgView.frame.size.width <= self.frame.size.width && imgView.frame.size.height <= self.frame.size.height)
{
//This code execute when we zoom out the image(small image then scroll view)
UIImage *imagetest =[self adjustForImageViewSmallInScroll:imgView targetSize:imgView.frame.size withCGPoint:CGPointMake(0,0)];
NSLog(@"SmallInScroll Shot %@",NSStringFromCGSize(imagetest.size));
return imagetest;
}
else
{
// CGSize sizeOriginal= imgView.image.size;
// CGSize sizeToCrop;
// CGPoint offsetToCrop;
// float widthCrop = (sizeOriginal.width*self.frame.size.width)/imgView.frame.size.width;
// float heightCrop = (sizeOriginal.height*self.frame.size.height)/imgView.frame.size.height;
// sizeToCrop = CGSizeMake(widthCrop, heightCrop);
//
// NSLog(@"size to Crop from image : %@",NSStringFromCGSize(sizeToCrop));
//
// // Offset to crop
// float xPointCrop = (sizeOriginal.width*self.contentOffset.x)/imgView.frame.size.width ;
// float yPointCrop = (sizeOriginal.height*self.contentOffset.y)/imgView.frame.size.height;
// offsetToCrop = CGPointMake(xPointCrop, yPointCrop);
//
// CGRect rectCrop ;
// rectCrop = CGRectMake(offsetToCrop.x,offsetToCrop.y,sizeToCrop.width,sizeToCrop.height);
//
// float scale = 1.0f/self.zoomScale;
// //ORIGNAL CODE JM END//
// CGImageRef imgRef = CGImageCreateWithImageInRect(imgView.image.CGImage, rectCrop);
// UIImage *img = [UIImage imageWithCGImage:imgRef scale:scale orientation:0];
// CGImageRelease(imgRef);
// return img;
//
CGRect Fi_iv = [self frameForImage:imgView.image inImageViewAspectFit:imgView];
//Frame ImageView in self.view coordinates
CGRect Fiv_sv = imgView.frame;
//Frame Image in self.view coordinates
CGRect Fi_sv = CGRectMake(Fi_iv.origin.x + Fiv_sv.origin.x
,Fi_iv.origin.y + Fiv_sv.origin.y,
Fi_iv.size.width, Fi_iv.size.height);
//ScrollView offset
CGPoint offset = self.contentOffset;
//Frame Image in offset coordinates
CGRect Fi_of = CGRectMake(Fi_sv.origin.x - offset.x,
Fi_sv.origin.y - offset.y,
Fi_sv.size.width,
Fi_sv.size.height);
CGFloat scale = imgView.image.size.width/Fi_of.size.width;
//the crop frame in image offset coordinates
CGRect Fcrop_iof = CGRectMake((self.frame.origin.x - Fi_of.origin.x)*scale,
(self.frame.origin.y - Fi_of.origin.y)*scale,
self.frame.size.width*scale,
self.frame.size.height*scale);
UIImage *image = [self image:imgView.image cropRect:Fcrop_iof];
// Use this crop image...
return image;
}
}
//Use this code to crop when you have the right frame
-(UIImage*)image:(UIImage *)image cropRect:(CGRect)frame
{
// Create a new UIImage
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, frame);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView
{
float imageRatio = image.size.width / image.size.height;
float viewRatio = imageView.frame.size.width / imageView.frame.size.height;
if(imageRatio < viewRatio)
{
float scale = imageView.frame.size.height / image.size.height;
float width = scale * image.size.width;
float topLeftX = (imageView.frame.size.width - width) * 0.5;
return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);
}
else
{
float scale = imageView.frame.size.width / image.size.width;
float height = scale * image.size.height;
float topLeftY = (imageView.frame.size.height - height) * 0.5;
return CGRectMake(0, topLeftY, imageView.frame.size.width, height);
}
}
-(UIImage *)adjustForImageViewSmallInScroll:(UIImageView *)imgViewAdj targetSize:(CGSize)sizeTarget withCGPoint:(CGPoint)point
{
CGRect scaledImageRect;
CGSize tempSize = [self getCGSizeAspectFitRatio:imgViewAdj.image.size withBoundImageSize:sizeTarget];
scaledImageRect = CGRectMake(point.x,point.y, tempSize.width, tempSize.height);
UIGraphicsBeginImageContextWithOptions(scaledImageRect.size, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor clearColor] setFill];
CGContextSetLineWidth(context, 4.0);
CGContextAddEllipseInRect(context, scaledImageRect);
[imgViewAdj.image drawInRect:scaledImageRect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSLog(@"Image size %@ ",NSStringFromCGSize(img.size));
return img;
}
-(UIImage *)getCropImageSecond
{
return [self cropImage:imgView.image inImageView:imgView scrollView:self];
}
-(UIImage*)cropImage:(UIImage*)image inImageView:(UIImageView*)imageView scrollView:(UIScrollView*)scrollView{
// get visible rect from image scrollview
CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:imageView];
UIImage* rCroppedImage;
CALayer* maskLayer= [[CALayer alloc] init];
maskLayer.contents= (id)image.CGImage;
maskLayer.frame= CGRectMake(0, 0, visibleRect.size.width, visibleRect.size.height);
CGRect rect= CGRectMake(visibleRect.origin.x / image.size.width,
visibleRect.origin.y / image.size.height,
visibleRect.size.width / image.size.width,
visibleRect.size.height / image.size.height);
maskLayer.contentsRect= rect;
UIGraphicsBeginImageContext(visibleRect.size);
CGContextRef context= UIGraphicsGetCurrentContext();
[maskLayer renderInContext:context];
rCroppedImage= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return rCroppedImage;
}