简体   繁体   中英

UIImageView image crop based on UIView mask

So i have an canvas (UIView) and a UIImageView, the canvas acts as a mask over the imageview

在此输入图像描述

i am using UIGestureRecognizers to zoom and rotate the UIImageView which is under the canvas.

i want to convert the final image (show in the canvas to a UIImage, one solution is to convert the canvas to an image like below

UIGraphicsBeginImageContext(self.canvas.bounds.size);
[self.canvas.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *newCombinedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

now this works fine but the problem with this solution is the image is cropped to the dimensions of the canvas so the resolution is very low.

another option i explored was to use some custom UIImage categories to rotate and scale.

[[[self.photoImage image] imageRotatedByDegrees:rotaton_angle] 
     imageAtRect:CGRectMake(x,y width,height)]

i need to provide rotation angle (the rotation angle provided by UIGesture Delegate is not in Degrees or Radians, then there is x,y,width,height, i imagine these needs to be calculated based on some scale, (i do get scale value from UIGesture delegate but they do not seem to be correct for this function)

there are a number of solutions here, that guides you to crop and image given a rect. but in my case the rect is not the same scale as the image also there is rotation involved.

any help will be appreciated.

i have managed to solve this, here is my solution, it most definitely isn't the cleanest, but it works.

i needed to handle 3 things, pan, zoom and rotate.

firstly i used the the UIGestureRecognizer Delegate to get cumulative values incrementing at UIGestureRecognizerStateEnded for all 3.

then for rotation i just used the UIImage Category discussed here

    self.imagetoEdit = [self.imagetoEdit imageRotatedByRadians:total_rotation];

for zooming (scale) i used GPUImage (i am using this throughout the app)

GPUImageTransformFilter *scaleFilter = [[GPUImageTransformFilter alloc] init];
[scaleFilter setAffineTransform:CGAffineTransformMakeScale(total_scale, total_scale)];
[scaleFilter prepareForImageCapture];
self.imagetoEdit = [scaleFilter imageByFilteringImage:self.imagetoEdit];

for panning, im doing this. (Not the cleanest code :S ) also using the above mention UIImage+Categories.

CGFloat x_ = (translation_point.x/canvas.frame.size.width)*self.imagetoEdit.size.width;
CGFloat y_ = (translation_point.y/canvas.frame.size.height)*self.imagetoEdit.size.height;
CGFloat xx = 0;
CGFloat yy = 0;
CGFloat ww = self.imagetoEdit.size.width-x_;
CGFloat hh = self.imagetoEdit.size.height-y_;

if (translation_point.x < 0) {
    xx = x_*-1;
    ww = self.imagetoEdit.size.width + xx;
}

if (translation_point.y < 0) {
    yy = y_*-1;
    hh = self.imagetoEdit.size.height + yy;
}

CGRect cgrect = CGRectMake(xx,yy, ww, hh);
self.imagetoEdit = [self.imagetoEdit imageAtRect:cgrect];

everything seem to work.

This might be helpful... Resizing a UIImage the right way

It might need some updating for ARC etc... though I think there are people who have done it and have posted it on Github.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM