문제

I have a UIImageView that has an image 640x1136. I want users to be able to scale and translate the image inside a cropping area (also 640x1136) then re-save the new cropped one at 640x1136 (pinch/pull/slide) so I stuck it in a UIScrollView and shrunk both of them down to around 100x178 and added scrolling capabilities -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {

Everything worked! I could move the image around, shrink and scale it, it was getting "clipped" at the edge of the subview! So now I am stuck trying to figure out how to snap a screenshot of it at max resolution? I can snap a screenshot with CGContext and it shows the proper "cropped" image section, but the resolution is 100x178, so I scale the whole thing up to 640x1136 then snap a screenshot but the problem is the content inside the scroll view doesn't scale up with it, so now the crop is all messed up! Are there any good solutions out there?


Here is the code I tried; it didn't work:

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(640, 1136), YES, 0.0);
    UIImageView *theImageToCrop = [[UIImageView alloc] initWithFrame:CGRectMake(0-(theScrollView.contentOffset.x*(640/theScrollView.frame.size.width)), 0-(theScrollView.contentOffset.y*(1136/theScrollView.frame.size.height)), theScrollView.contentSize.width*(640/theScrollView.frame.size.width), theScrollView.contentSize.height*(1136/theScrollView.frame.size.height))];
    theImageToCrop.contentMode = UIViewContentModeScaleAspectFill;
    theImageToCrop.image = originalImageView.image;
    CGContextRef context = UIGraphicsGetCurrentContext();
    [theImageToCrop.layer renderInContext:context];
    croppedImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

I can already tell the problem is that the image is not being translated when I take the final screenshot. It is scaling to the proper size that it was scaled to in the UIImageView but the content offset is not being set. I am setting it in the frame I create with CGRectMake but I have a feeling that when I use this code: [theImageToCrop.layer renderInContext:context]; the size is maintained but the origin is reset to (0,0). How can I keep the size and origin?

도움이 되었습니까?

해결책

Couldn't figure out how to translate after renderInContext is applied to a layer... so rather than sticking the scaled UIImageView's layer into renderInContext I created a UIView the same size at origin (0,0) then I added the imageView as a subview to the UIView I just created and translated it within the view THEN I applied renderInContext to that view!

UIGraphicsBeginImageContextWithOptions(CGSizeMake(640, 1136), YES, 0.0);
UIView *theImageHolder = [[UIView alloc] initWithFrame:CGRectMake(0,0,640,1136)];
UIImageView *theImageToCrop = [[UIImageView alloc] initWithFrame:CGRectMake(0-(theScrollView.contentOffset.x*(640/theScrollView.frame.size.width)), 0-(theScrollView.contentOffset.y*(1136/theScrollView.frame.size.height)), theScrollView.contentSize.width*(640/theScrollView.frame.size.width), theScrollView.contentSize.height*(1136/theScrollView.frame.size.height))];
theImageToCrop.contentMode = UIViewContentModeScaleAspectFill;
theImageToCrop.image = originalImageView.image;
CGContextRef context = UIGraphicsGetCurrentContext();
[theImageHolder addSubview:theImageToCrop];
[theImageHolder.layer renderInContext:context];
croppedImage.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

edit: It should be noted that if the user has NOT made any adjustments to the image rather than leaving the image as is when preforming the crop it will return an image of width:height = 0:0 ... this is because contentSize is 0:0 ... To fix this instead of using contentSize in the UIImageView CGRectMake code use a float variable and define the float variables in a way that if they are equal to zero they just get set to the size of your UIScrollView frame (the same size they would be had the user not pinched them at all to scale!

float scaleWidth = imageAdjustView.contentSize.width;
float scaleHeight = imageAdjustView.contentSize.height;
if (scaleWidth == 0) {
    scaleWidth = imageAdjustView.frame.size.width;
}
if (scaleHeight == 0) {
    scaleHeight = imageAdjustView.frame.size.height;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top