Getting a resized screenshot from a UIView

2020-07-27 05:03发布

问题:

I'm trying to take a screenshot of a UIView shrunk down to thumbnail size with the following code,

    UIGraphicsBeginImageContext(size);
    [canvas.layer renderInContext:UIGraphicsGetCurrentContext()];
    result = [UIGraphicsGetImageFromCurrentImageContext() retain];
    UIGraphicsEndImageContext();

The above code will simply grab the top left portion of the view in the original unshrunk size instead.

I'm sure I've done this before, but I just can't get it working. Anyone know what's off here?

回答1:

Supposing that you have a CGSize origSize which is the original size (e.g. 768x1024) and a CGSize size which is the required size, this can be done like so:

CGFloat scaleX = size.width / origSize.width;
CGFloat scaleY = size.height / origSize.height;
UIGraphicsBeginImageContextWithOptions(origSize, NO, scaleX > scaleY ? scaleY : scaleX);
[canvas.layer renderInContext:UIGraphicsGetCurrentContext()];
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Note that we're using origSize in the begun context, not size. The scale affects the size as well.

Update (roughly a year later): note that this technique interferes with (or is interefered by) transforms on the UIView being snapshotted. If the above is not working and you're doing scale transforms on the view (or its layer), you may wanna go with this solution: How to scale down a UIImage and make it crispy / sharp at the same time instead of blurry?



回答2:

I find that this solution generates thumbnails that are the right size.

    let thumbRect = CGRect(x: 0, y: 0, width: 512, height: 666)
    UIGraphicsBeginImageContext(thumbSize)
    let context = UIGraphicsGetCurrentContext()     
    self.view.frame = thumbRect
    self.view.layer.renderInContext(context)
    thumbImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

However, the resized image adopts the trait collection from the original view controller. So although the size is correct, some auto layout features still end-up visible in the resulting image.