Search code examples
iosipadavfoundationscreenshotuigraphicscontext

iOS Screen Capture and Performance


I am trying to periodically capture the screen of an iDevice (every second or when the user touches the screen). I am doing this with a subclassed UIView, where the hitTest method calls the following:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSString *pngTitle = [NSString stringWithFormat:@"Documents/Test%d.jpg", imageIdentifier];
NSString  *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:pngTitle];
int tempIdentifier = imageIdentifier+1;
imageIdentifier = tempIdentifier;
[UIImageJPEGRepresentation(capturedScreen, 0.4f) writeToFile:pngPath atomically:YES];

NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
[fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error];

Capturing the screen content works fine, however, it also causes such a dramatic performance drop that it makes the application I embedded it in virtually unusable. It becomes so sluggish that swipe gestures, for instance, do not register any more on scroll views.

Is there a way to capture screen images that does not affect performance (or at least not this much)?

Thank you!


Solution

  • Use GCD for your requirement: I assume u call getScreen every 1 second then:

    -(void)getScreen
    {
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
     dispatch_async(queue, ^{
        UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
        CGRect rect = [keyWindow bounds];
        UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [keyWindow.layer renderInContext:context];
        UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        NSString *pngTitle = [NSString stringWithFormat:@"Documents/Test%d.jpg", imageIdentifier];
        NSString  *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:pngTitle];
        imageIdentifier = imageIdentifier+1;
        [UIImageJPEGRepresentation(capturedScreen, 0.4f) writeToFile:pngPath atomically:YES];
    
        NSError *error;
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
        [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error];
    
      dispatch_sync(dispatch_get_main_queue(), ^{
        [self performSelector:@selector(getScreen) withObject:nil afterDelay:1.0];
      });
      });
     }