¿Cómo tomo una captura de pantalla de una UIView?

Resuelto cduck asked hace 54 años • 16 respuestas

Me pregunto cómo mi aplicación de iPhone puede tomar una captura de pantalla de un archivo específico UIViewcomo archivo UIImage.

Probé este código pero lo único que obtengo es una imagen en blanco.

UIGraphicsBeginImageContext(CGSizeMake(320,480));
CGContextRef context = UIGraphicsGetCurrentContext();
[myUIView.layer drawInContext:context];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

myUIViewTiene dimensiones 320x480 y tiene algunas subvistas. ¿Cuál es la forma correcta de hacer esto?

cduck avatar Jan 01 '70 08:01 cduck
Aceptado

iOS 7 tiene un nuevo método que le permite dibujar una jerarquía de vistas en el contexto gráfico actual. Esto se puede utilizar para obtener una UIImage muy rápido.

Implementé un método de categoría para UIViewobtener la vista como UIImage:

- (UIImage *)pb_takeSnapshot {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);

    [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];

    // old style [self.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

Es considerablemente más rápido que el renderInContext:método existente.

Referencia: https://developer.apple.com/library/content/qa/qa1817/_index.html

ACTUALIZACIÓN PARA SWIFT : Una extensión que hace lo mismo:

extension UIView {

    func pb_takeSnapshot() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.mainScreen().scale)

        drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)

        // old style: layer.renderInContext(UIGraphicsGetCurrentContext())

        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

ACTUALIZACIÓN PARA SWIFT 3

    UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)

    drawHierarchy(in: self.bounds, afterScreenUpdates: true)

    let image = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
Klaas avatar Sep 20 '2013 20:09 Klaas

Creo que quizás quieras renderInContext, no drawInContext. drawInContext es más un método que usted anularía...

Tenga en cuenta que es posible que no funcione en todas las vistas, específicamente hace aproximadamente un año, cuando intenté usar esto con la vista de cámara en vivo, no funcionó.

Kendall Helmstetter Gelner avatar Feb 06 '2010 23:02 Kendall Helmstetter Gelner

Debe capturar la ventana clave para una captura de pantalla o una UIView. Puede hacerlo en Resolución Retina usando UIGraphicsBeginImageContextWithOptions y establecer su parámetro de escala en 0.0f. Siempre captura en resolución nativa (retina para iPhone 4 y posteriores).

Este hace una captura de pantalla completa (ventana clave)

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();

Este código captura una UIView en resolución nativa

CGRect rect = [captureView bounds];
UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
[captureView.layer renderInContext:context];   
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Esto guarda la UIImage en formato jpg con un 95% de calidad en la carpeta de documentos de la aplicación si es necesario.

NSString  *imagePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"Documents/capturedImage.jpg"]];    
[UIImageJPEGRepresentation(capturedImage, 0.95) writeToFile:imagePath atomically:YES];
Tibidabo avatar May 15 '2012 09:05 Tibidabo

iOS7 en adelante, tenemos los siguientes métodos predeterminados:

- (UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates

Llamar al método anterior es más rápido que intentar representar usted mismo el contenido de la vista actual en una imagen de mapa de bits.

Si desea aplicar un efecto gráfico, como desenfoque, a una instantánea, utilice este drawViewHierarchyInRect:afterScreenUpdates:método.

https://developer.apple.com/library/ios/documentation/uikit/reference/uiview_class/uiview/uiview.html

san avatar Jan 20 '2014 09:01 san

Hay una nueva API de iOS 10

extension UIView {
    func makeScreenshot() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
        return renderer.image { (context) in
            self.layer.render(in: context.cgContext)
        }
    }
}
Mike Demidov avatar May 01 '2018 13:05 Mike Demidov