2012-06-11 18 views
11

¿Cómo hago una captura de pantalla 1: 1 del área visible de UIScrollView? El contenido puede ser más grande o más pequeño que los límites de UIScrollView, así como medio oculto (he implementado el desplazamiento personalizado para contenido más pequeño, por lo que no está en la esquina superior izquierda). que he logrado el resultado deseado en el simulador, pero no en el dispositivo en sí:¿Cómo tomar una captura de pantalla del área visible de UIScrollView?

-(UIImage *)imageFromCombinedContext:(UIView *)background { 
     UIImage *image; 
     CGRect vis = background.bounds; 
     CGSize size = vis.size; 
     UIGraphicsBeginImageContext(size); 
     [background.layer affineTransform]; 
     [background.layer renderInontext:UIGraphicsGetCurrentContext()]; 
     image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
     CGImageRef imref = CGImageCreateWithImageInRect([image CGImage], vis); 
     image = [UIImage imageWithCGImage:imref]; 
     CGImageRelease(imref); 
     return image; 
} 

Respuesta

4

he encontrado una solución a mí mismo - Tomé captura de pantalla de la visión de conjunto y después recortar al tamaño y la posición del marco de UIScrollView .

-(UIImage *)imageFromCombinedContext:(UIView *)background 
{ 
     UIImage *image; 
     CGSize size = self.view.frame.size; 
     UIGraphicsBeginImageContext(size); 
     [background.layer affineTransform]; 
     [self.view.layer.layer renderInContext:UIGraphicsGetCurrentContext()]; 
     image = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
     CGImageRef imgRef = CGImageCreateWithImageInRect([image CGImage],background.frame); 
     image = [UIImage imageWithCGImage:imref]; 
     CGImageRelease(imref); 
     return image; 
} 
+0

aceptar su respuesta entonces :) – ant

+0

Todavía tengo que esperar 20 horas) – Concuror

+2

¿No es esto terriblemente ineficaz para grandes vistas de desplazamiento? ¿Qué pasa con la respuesta de @AbduliamRehmanius? – deanWombourne

29

Otro enfoque sería el uso de la contentOffset para ajustar el área visible de la capa y capturar única el área visible de UIScrollView.

UIScrollView *contentScrollView;....//scrollview instance 

UIGraphicsBeginImageContextWithOptions(contentScrollView.bounds.size, 
             YES, 
             [UIScreen mainScreen].scale); 

//this is the key 
CGPoint offset=contentScrollView.contentOffset; 
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -offset.x, -offset.y); 

[contentScrollView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *visibleScrollViewImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

Saludos :)

+3

esto es mucho más simple y la memoria optimizada ya que no hay necesidad de recortar una imagen más grande. –

+1

Esta respuesta es la única que funcionó para mí. Gracias. –

+0

¿Alguien tiene suerte con esto en Swift?Tengo un ScrollView "zoom", llamar a esta función de extensión y obtener una imagen vacía: func captura de pantalla() -> UIImage { offset = self.contentOffset UIGraphicsBeginImageContextWithOptions (self.bounds.size, falso, UIScreen.mainScreen let() .scale) CGContextTranslateCTM (UIGraphicsGetCurrentContext(), -offset.x, -offset.y) self.layer.renderInContext (UIGraphicsGetCurrentContext() imagen deja!) = UIGraphicsGetImageFromCurrentImageContext() imagen de retorno UIGraphicsEndImageContext() } – Ryan

0

respuesta de @Abduliam Rehmanius tiene un rendimiento deficiente, ya que si el UIScrollView contiene una gran área de contenido, vamos a sacar toda esa área de contenido (incluso fuera de los límites visibles). La respuesta de @Cocuror tiene el problema de que también dibujará cualquier cosa que esté encima del UIScrollView.

Mi solución fue poner el UIScrollView dentro de una llamada UIViewcontainerView con los mismos límites y luego hacer containerView:

containerView.renderInContext(context) 
3

Jeffery Sun tiene la respuesta correcta. Simplemente coloque su vista de desplazamiento dentro de otra vista. Obtenga vista de contenedor para renderizar en contexto. hecho.

En el código siguiente, cropView contiene la vista de desplazamiento que se va a capturar. La solución es así de simple.

Como tengo entendido la pregunta y por qué encontré esta página, no se desea todo el contenido de la vista de desplazamiento, solo la parte visible.

func captureCrop() -> UIImage { 
    UIGraphicsBeginImageContextWithOptions(self.cropView.frame.size, true, 0.0) 
    self.cropView.layer.renderInContext(UIGraphicsGetCurrentContext()) 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image; 
} 
3

Versión rápida de Abduliam Rehmanius answer.

func screenshot() -> UIImage { 

     UIGraphicsBeginImageContextWithOptions(self.scrollCrop.bounds.size, true, UIScreen.mainScreen().scale); 
     //this is the key 
     let offset:CGPoint = self.scrollCrop.contentOffset; 
     CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -offset.x, -offset.y); 
     self.scrollCrop.layer.renderInContext(UIGraphicsGetCurrentContext()!); 
     let visibleScrollViewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext(); 
     UIGraphicsEndImageContext(); 
     return visibleScrollViewImage; 
    } 
0

Swift 3.0:

func captureScreen() -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(self.yourScrollViewName.bounds.size, true, UIScreen.main.scale) 
    let offset:CGPoint = self.yourScrollViewName.contentOffset; 
    UIGraphicsGetCurrentContext()!.translateBy(x: -offset.x, y: -offset.y); 
    self.yourScrollViewName.layer.render(in: UIGraphicsGetCurrentContext()!) 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 
    return image 
} 

y utilizarlo como: Let imagen = CaptureScreen()

0

actualización rápida 3+, 4 en el código @Concuror

func getImage(fromCombinedContext background: UIView) -> UIImage { 
     var image: UIImage? 
     let size: CGSize = view.frame.size 
     UIGraphicsBeginImageContext(size) 
     background.layer.affineTransform() 
     view.layer.render(in: UIGraphicsGetCurrentContext()!) 
     image = UIGraphicsGetImageFromCurrentImageContext() 
     UIGraphicsEndImageContext() 
     let imgRef = image?.cgImage?.cropping(to: background.frame) 
     image = UIImage(cgImage: imgRef!) 
     // CGImageRelease(imgRef!) // Removing on Swift - 'CGImageRelease' is unavailable: Core Foundation objects are automatically memory managed 
     return image ?? UIImage() 
    } 
Cuestiones relacionadas