11
votes

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

enter image description here

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.

2
Can you post the code that gets the rotation from the gesture recognizer? You say you don't get the rotation in radians, but the header for UIRotationGestureRecognizer claims that its rotation property is given in radians. You should be able to take the rotation from a UIRotationGestureRecognizer and use it in your imageRotatedByDegress:imageAtRect: method.Aaron Golden
@AaronGolden yes u are correct, however the value is for a singe movement, i have manage to get the cumulative value, im able to do rotation and zooming to match now. just need to figure out the panning and im good to go.Jinah Adam

2 Answers

2
votes

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.

1
votes

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.