How to crop a UIImageView to a new UIImage in 'aspect fit' mode?

后端 未结 4 1094
一生所求
一生所求 2020-12-28 10:51

\"enter

I would like to create a new UIImage by cropping the image inside a UIImageVie

相关标签:
4条回答
  • 2020-12-28 10:54

    I know the answer has been but I had some problems getting above right so, I wont to post my solution too.

    The problem is the image is scaled with a aspect fit, but we know the scale factor for both the width and the height. Then we can calculate the right cropping rectangle pretty easy:

    -(UIImage*)crop:(CGRect)frame
    {
        // Find the scalefactors  UIImageView's widht and height / UIImage width and height
        CGFloat widthScale = self.bounds.size.width / self.image.size.width;
        CGFloat heightScale = self.bounds.size.height / self.image.size.height;
    
        // Calculate the right crop rectangle 
        frame.origin.x = frame.origin.x * (1 / widthScale);
        frame.origin.y = frame.origin.y * (1 / heightScale);
        frame.size.width = frame.size.width * (1 / widthScale);
        frame.size.height = frame.size.height * (1 / heightScale);
    
        // Create a new UIImage
        CGImageRef imageRef = CGImageCreateWithImageInRect(self.image.CGImage, frame);
        UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef);
    
        return croppedImage;
    }
    
    0 讨论(0)
  • 2020-12-28 10:54

    I use the method below.

    -(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
    {
       CGSize cropSize = rect.size;
       CGFloat widthScale =  
       image.size.width/self.imageViewOriginal.bounds.size.width;
       CGFloat heightScale = 
       image.size.height/self.imageViewOriginal.bounds.size.height;
       cropSize = CGSizeMake(rect.size.width*widthScale,  
       rect.size.height*heightScale);
       CGPoint  pointCrop = CGPointMake(rect.origin.x*widthScale, 
       rect.origin.y*heightScale);
       rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, 
       cropSize.height);
       CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
       UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
       CGImageRelease(subImage);
       return croppedImage;
    
       }
    
    0 讨论(0)
  • 2020-12-28 11:02

    Based on my other answer to a similar question I have written this method for a UIImageView category:

    -(CGRect) cropRectForFrame:(CGRect)frame
    {
        NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, @"content mode must be aspect fit");
    
        CGFloat widthScale = self.bounds.size.width / self.image.size.width;
        CGFloat heightScale = self.bounds.size.height / self.image.size.height;
    
        float x, y, w, h, offset;
        if (widthScale<heightScale) {
            offset = (self.bounds.size.height - (self.image.size.height*widthScale))/2;
            x = frame.origin.x / widthScale;
            y = (frame.origin.y-offset) / widthScale;
            w = frame.size.width / widthScale;
            h = frame.size.height / widthScale;
        } else {
            offset = (self.bounds.size.width - (self.image.size.width*heightScale))/2;
            x = (frame.origin.x-offset) / heightScale;
            y = frame.origin.y / heightScale;
            w = frame.size.width / heightScale;
            h = frame.size.height / heightScale;
        }
        return CGRectMake(x, y, w, h);
    }
    

    You can pass in the frame of your green rect (assuming it is a subview of the image view) and get the crop rect back for cropping the UIImage. Note that it only works for 'aspect fit' mode! I haven't tested it though. So, tell me if it works!

    0 讨论(0)
  • 2020-12-28 11:08

    I think you don't understand what you are doing. You can't "crop" a UIImageView - only UIImages. So your croppedImage method should be in a UIImage category and not a UIImageView category. The bounds rect you pass to the crop method must be in relation to the image size, not to the imageview bounds. It is irrelevant what the contentMode of the image view is - the cropping of the image will always work the same. First get the image from the image view. Then create a new cropped image from it and finally set the cropped image for the image view. This can be done in one line of code:

    imageView.image = [imageView.image croppedImage:rect];
    

    Since your contentMode is 'aspect fit' the new image will automatically stretch to fit in the view frame. You can also try to change the view frame based on the image.size to avoid pixelation effects.

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题