How to take a screenshot programmatically on iOS

前端 未结 20 2099
一生所求
一生所求 2020-11-22 01:42

I want a screenshot of the image on the screen saved into the saved photo library.

相关标签:
20条回答
  • 2020-11-22 02:07

    This will work with swift 4.2, the screenshot will be saved in library, but please don't forget to edit the info.plist @ NSPhotoLibraryAddUsageDescription :

      @IBAction func takeScreenshot(_ sender: UIButton) {
    
        //Start full Screenshot
        print("full Screenshot")
        UIGraphicsBeginImageContext(card.frame.size)
        view.layer.render(in: UIGraphicsGetCurrentContext()!)
        var sourceImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        UIImageWriteToSavedPhotosAlbum(sourceImage!, nil, nil, nil)
    
        //Start partial Screenshot
        print("partial Screenshot")
        UIGraphicsBeginImageContext(card.frame.size)
        sourceImage?.draw(at: CGPoint(x:-25,y:-100)) //the screenshot starts at -25, -100
        var croppedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        UIImageWriteToSavedPhotosAlbum(croppedImage!, nil, nil, nil)
    
    }
    
    0 讨论(0)
  • 2020-11-22 02:08
    - (UIImage*) getGLScreenshot {
        NSInteger myDataLength = 320 * 480 * 4;
    
        // allocate array and read pixels into it.
        GLubyte *buffer = (GLubyte *) malloc(myDataLength);
        glReadPixels(0, 0, 320, 480, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
    
        // gl renders "upside down" so swap top to bottom into new array.
        // there's gotta be a better way, but this works.
        GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
        for(int y = 0; y <480; y++)
        {
            for(int x = 0; x <320 * 4; x++)
            {
                buffer2[(479 - y) * 320 * 4 + x] = buffer[y * 4 * 320 + x];
            }
        }
    
        // make data provider with data.
        CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
    
        // prep the ingredients
        int bitsPerComponent = 8;
        int bitsPerPixel = 32;
        int bytesPerRow = 4 * 320;
        CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
        CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
        CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    
        // make the cgimage
        CGImageRef imageRef = CGImageCreate(320, 480, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
    
        // then make the uiimage from that
        UIImage *myImage = [UIImage imageWithCGImage:imageRef];
        return myImage;
    }
    
    - (void)saveGLScreenshotToPhotosAlbum {
        UIImageWriteToSavedPhotosAlbum([self getGLScreenshot], nil, nil, nil);  
    }
    

    Source.

    0 讨论(0)
  • 2020-11-22 02:09
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0);
    [self.myView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSData *imageData = UIImageJPEGRepresentation(image, 1.0 ); //you can use PNG too
    [imageData writeToFile:@"image1.jpeg" atomically:YES];
    
    0 讨论(0)
  • 2020-11-22 02:09

    As of iOS10, this gets a bit simpler. UIKit comes with UIGraphicsImageRender that allows you to

    ... accomplish drawing tasks, without having to handle configuration such as color depth and image scale, or manage Core Graphics contexts

    Apple Docs - UIGraphicsImageRenderer

    So you can now do something like this:

    let renderer = UIGraphicsImageRenderer(size: someView.bounds.size)
    
    let image = renderer.image(actions: { context in
        someView.drawHierarchy(in: someView.bounds, afterScreenUpdates: true)
    })
    

    Many of the answers here worked for me in most cases. But when trying to take a snapshot of an ARSCNView, I was only able to do it using the method described above. Although it might be worth noting that at this time, ARKit is still in beta and Xcode is in beta 4

    0 讨论(0)
  • 2020-11-22 02:12

    I couldn't find an answer with Swift 3 implementation. So here it goes.

    static func screenshotOf(window: UIWindow) -> UIImage? {
    
        UIGraphicsBeginImageContextWithOptions(window.bounds.size, true, UIScreen.main.scale)
    
        guard let currentContext = UIGraphicsGetCurrentContext() else {
            return nil
        }
    
        window.layer.render(in: currentContext)
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else {
            UIGraphicsEndImageContext()
            return nil
        }
    
        UIGraphicsEndImageContext()
        return image
    }
    
    0 讨论(0)
  • 2020-11-22 02:12

    Two options available at bellow site:

    OPTION 1: using UIWindow (tried and work perfectly)

    // create graphics context with screen size
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    UIGraphicsBeginImageContext(screenRect.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor blackColor] set];
    CGContextFillRect(ctx, screenRect);
    
    // grab reference to our window
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    
    // transfer content into our context
    [window.layer renderInContext:ctx];
    UIImage *screengrab = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    OPTION 2: using UIView

    // grab reference to the view you'd like to capture
    UIView *wholeScreen = self.splitViewController.view;
    
    // define the size and grab a UIImage from it
    UIGraphicsBeginImageContextWithOptions(wholeScreen.bounds.size, wholeScreen.opaque, 0.0);
    [wholeScreen.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screengrab = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    For retina screen (as DenNukem answer)

    // grab reference to our window
        UIWindow *window = [UIApplication sharedApplication].keyWindow;
    
        // create graphics context with screen size
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
            UIGraphicsBeginImageContextWithOptions(screenRect.size, NO, [UIScreen mainScreen].scale);
        } else {
            UIGraphicsBeginImageContext(screenRect.size);
            [window.layer renderInContext:UIGraphicsGetCurrentContext()];
        }
    

    for more detail: http://pinkstone.co.uk/how-to-take-a-screeshot-in-ios-programmatically/

    0 讨论(0)
提交回复
热议问题