문제

After successfully using UIView’s new drawViewHierarchyInRect:afterScreenUpdates: method introduced in iOS 7 to obtain an image representation (via UIGraphicsGetImageFromCurrentImageContext()) for blurring my app also needed to obtain just a portion of a view. I managed to get it in the following manner:

UIImage *image;

CGSize blurredImageSize = [_blurImageView frame].size;

UIGraphicsBeginImageContextWithOptions(blurredImageSize, YES, .0f);

[aView drawViewHierarchyInRect: [aView bounds] afterScreenUpdates: YES];

image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

This lets me retrieve aView’s content following _blurImageView’s frame.

Now, however, I would need to obtain a portion of aView, but this time this portion would be “inside”. Below is an image representing what I would like to achieve.

I have already tried creating a new graphics context and setting its size to the portion’s size (red box) and calling aView to draw in the rect that represents the red box’s frame (of course its superview’s frame being equal to aView’s) but the image obtained is all black (empty).

도움이 되었습니까?

해결책

After a lot of tweaking I managed to find something that did the job, however I heavily doubt this is the way to go.

Here’s my [edited-for-Stack Overflow] code that works:

- (UIImage *) imageOfPortionOfABiggerView
{
    UIView *bigViewToExtractFrom;

    UIImage *image;

    UIImage *wholeImage;

    CGImageRef _image;

    CGRect imageToExtractFrame;

    CGFloat screenScale = [[UIScreen mainScreen] scale];

    // have to scale the rect due to (I suppose) the screen's scale for Core Graphics.

    imageToExtractFrame = CGRectApplyAffineTransform(imageToExtractFrame, CGAffineTransformMakeScale(screenScale, screenScale));



    UIGraphicsBeginImageContextWithOptions([bigViewToExtractFrom bounds].size, YES, screenScale);

    [bigViewToExtractFrom drawViewHierarchyInRect: [bigViewToExtractFrom bounds] afterScreenUpdates: NO];

    wholeImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    // obtain a CGImage[Ref] from another CGImage, this lets me specify the rect to extract.
    // However since the image is from a UIView which are all at 2x scale (retina) if you specify a rect in points CGImage will not take the screen's scale into consideration and will process the rect in pixels. You'll end up with an image from the wrong rect and half the size.

    _image = CGImageCreateWithImageInRect([wholeImage CGImage], imageToExtractFrame);

    wholeImage = nil;

    // have to specify the image's scale due to CGImage not taking the screen's scale into consideration.

    image = [UIImage imageWithCGImage: _image scale: screenScale orientation: UIImageOrientationUp];

    CGImageRelease(_image);

    return image;
}

I hope this will help anyone that stumped upon my issue. Feel free to improve my snippet.

Thanks

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top