当图像尺寸小于外部视图并且用户缩放该图像时裁剪图像问题?

时间:2015-10-31 11:05:37

标签: ios objective-c uiscrollview uiimageview crop

当原始图像尺寸小于特定裁剪类视图(300,300)并且用户在那时缩放该时间裁剪图像变得不精确(300,300)时,裁剪图像出现问题。在下面我添加了代码:

Actual image in view

small image like 64 by 64 zoom

What i get after zoom small image i need (300,300)

Class @interface CropImage:UIScrollView

 #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;
}

0 个答案:

没有答案