Search code examples
iosobjective-cscreenshotquartz-core

Objective-C: Capture screenshot of all views within custom frame


I have a game where users can create custom levels and upload them to my server for other users to play and I want to get a screenshot of the "action area" before the user tests his/her level to upload to my server as sort of a "preview image".

I know how to get a screenshot of the entire view, but I want to define it to a custom frame. Consider the following image:

Action Area

I want to just take a screenshot of the area in red, the "action area." Can I achieve this?


Solution

  • Just you need to make a rect of the area you want to be captured and pass the rect in the method.

    Swift 3.x :

    extension UIView {
      func imageSnapshot() -> UIImage {
        return self.imageSnapshotCroppedToFrame(frame: nil)
      }
    
      func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
        let scaleFactor = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
        self.drawHierarchy(in: bounds, afterScreenUpdates: true)
        var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
    
        if let frame = frame {
            let scaledRect = frame.applying(CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
    
            if let imageRef = image.cgImage!.cropping(to: scaledRect) {
                image = UIImage(cgImage: imageRef)
            }
        }
        return image
      }
    }
    
    //How to call :
    imgview.image = self.view.imageSnapshotCroppedToFrame(frame: CGRect.init(x: 0, y: 0, width: 320, height: 100))
    

    Objective C :

    -(UIImage *)captureScreenInRect:(CGRect)captureFrame 
    {
        CALayer *layer;
        layer = self.view.layer;
        UIGraphicsBeginImageContext(self.view.bounds.size); 
        CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
        [layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return screenImage;
    }
    
    //How to call :
    imgView.image = [self captureScreenInRect:CGRectMake(0, 0, 320, 100)];