0

I have a UIView. There is a UIImageView inside that UIView. UIImageView doesn't comply to autolayout constraints. Parent UIView's bounds are clipped. Now content mode of UIImageView is Aspect Fill, but the size of UIImageView is always calculated and set to size of UIImage that is being rendered. So UIImageView's size will always be equal to size of UIImage.

Now UIImageView can be positioned. It has a pan gesture applied to it. UIImageView is being moved within the parent UIView based on requirement of user.

My task is to crop the UIImage of UIImageView to the visible viewport of parent UIVIew only. Core Cropping the image is not issue but finding the visible rect is.

My solution which is not working was to convert frame of parent UIView and child UIImageView to window screen. Then find the intersection of new converted frames. But this is not working. There should be some simple mathematics behind this which I am not able to come up successfully.

This is my code so far.

CGRect imgFrame = [_pageImageView convertRect:_pageImageView.frame toView:nil];
CGRect viewportFrame = [_viewportView convertRect: _viewportView.frame toView:nil];

CGRect visibleRect = CGRectIntersection(imgFrame, viewportFrame);

CGImageRef imageRef = CGImageCreateWithImageInRect([_pageImageView.image CGImage], visibleRect);
UIImage *cropped = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

My objective is to find the visible rect that is visible through clipped parent UIVIew, then crop the UIImageView based on that visible rect. Important note: UIImageView can be positioned and moved within parent UIView.

EDIT: I can't use UIScrollView for cropping as used in many other discussions for my internal reasons.

Cœur
  • 37,241
  • 25
  • 195
  • 267
padam thapa
  • 1,471
  • 2
  • 20
  • 41

1 Answers1

0

You can place the image view inside the UIScrollView instead of UIView which make the pan gesture work easier. I have the scrollview have the UIImageView

- (CGRect)imageCropRect
{
    CGSize imageSize = self.image.size;
    CGSize contentSize = self.contentSize;

    CGRect cropBoxFrame = self.frame;
    CGPoint contentOffset = self.contentOffset;
    UIEdgeInsets edgeInsets = self.contentInset;

    CGRect frame = CGRectZero;
    frame.origin.x = floor((contentOffset.x + edgeInsets.left) * (imageSize.width / contentSize.width));
    frame.origin.x = MAX(0, frame.origin.x);

    frame.origin.y = floor((contentOffset.y + edgeInsets.top) * (imageSize.height / contentSize.height));
    frame.origin.y = MAX(0, frame.origin.y);

    frame.size.width = ceil(cropBoxFrame.size.width * (imageSize.width / contentSize.width));
    frame.size.width = MIN(imageSize.width, frame.size.width);

    frame.size.height = ceil(cropBoxFrame.size.height * (imageSize.height / contentSize.height));
    frame.size.height = MIN(imageSize.height, frame.size.height);

    return frame;
}
  • I can't use UIScrollView for few internal reasons, and problem is not pan gesture and movement. They are all working fine and easy too. Solution needs to be around given foundation. – padam thapa Dec 20 '18 at 11:15