Como tirar uma captura de canvas programaticamente

Quero uma captura de canvas da imagem na canvas salva na biblioteca de fotos salva

Considerando uma verificação de exibição de retina, use o seguinte trecho de código:

#import  if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale); } else { UIGraphicsBeginImageContext(self.window.bounds.size); } [self.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSData *imageData = UIImagePNGRepresentation(image); if (imageData) { [imageData writeToFile:@"screenshot.png" atomically:YES]; } else { NSLog(@"error while taking screenshot"); } 

Abaixo método funciona para objects OPENGL também

 //iOS7 or above - (UIImage *) screenshot { CGSize size = CGSizeMake(your_width, your_height); UIGraphicsBeginImageContextWithOptions(size, NO, [UIScreen mainScreen].scale); CGRect rec = CGRectMake(0, 0, your_width, your_height); [_viewController.view drawViewHierarchyInRect:rec afterScreenUpdates:YES]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } 
 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]; 
 - (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); } 

Fonte

Veja este post parece que você pode usar UIGetScreenImage () por agora.

EM SWIFT

 func captureScreen() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, 0); self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true) let image: UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } 

Isso salvará uma captura de canvas e também retornará a captura de canvas.

 -(UIImage *)capture{ UIGraphicsBeginImageContext(self.view.bounds.size); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *imageView = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIImageWriteToSavedPhotosAlbum(imageView, nil, nil, nil); //if you need to save return imageView; } 

Eu acho que o seguinte trecho ajudaria se você quiser ter uma canvas cheia ( exceto para a barra de status ), basta replace AppDelegate com o nome do delegado do seu aplicativo, se necessário.

 - (UIImage *)captureFullScreen { AppDelegate *_appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { // for retina-display UIGraphicsBeginImageContextWithOptions(_appDelegate.window.bounds.size, NO, [UIScreen mainScreen].scale); [_appDelegate.window drawViewHierarchyInRect:_appDelegate.window.bounds afterScreenUpdates:NO]; } else { // non-retina-display UIGraphicsBeginImageContext(_bodyView.bounds.size); [_appDelegate.window drawViewHierarchyInRect:_appDelegate.window.bounds afterScreenUpdates:NO]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } 

Não consegui encontrar uma resposta com a implementação do Swift 3. Então aqui vai.

 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 } 

A partir do iOS10, isso fica um pouco mais simples. UIKit vem com UIGraphicsImageRender que permite que você

… realizar tarefas de desenho, sem ter que lidar com configuração, como profundidade de cor e escala de imagem, ou gerenciar contextos de charts principais

Apple Docs – UIGraphicsImageRenderer

Então você pode fazer algo assim:

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

Muitas das respostas aqui funcionaram para mim na maioria dos casos. Mas ao tentar tirar uma foto de um ARSCNView , eu só consegui fazer isso usando o método descrito acima. Embora possa ser interessante notar que, neste momento, o ARKit ainda está em beta e o Xcode está em beta 4

Obter captura de canvas da vista

 -(UIImage *)getScreenshotImage { if ([[UIScreen mainScreen] scale] == 2.0) { UIGraphicsBeginImageContextWithOptions(self.view.frame.size, FALSE, 2.0); } else { UIGraphicsBeginImageContextWithOptions(self.view.frame.size, FALSE, 1.0); } [self.view.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } 

Salvar imagem em fotos

 UIImageWriteToSavedPhotosAlbum(YOUR_IMAGE, nil, nil, nil); 

Como

 UIImageWriteToSavedPhotosAlbum([self getScreenshotImage], nil, nil, nil); 

Para iOS 7.0 ou superior ..

Se você quiser tirar screenshots da view say (myView), você pode fazer isso com uma única linha:

 [myView snapshotViewAfterScreenUpdates:NO]; 

Outra opção é usar a ferramenta de automação em instrumentos. Você escreve um roteiro para colocar a canvas no estado que você quer, então tire as fotos. Aqui está o script que usei para um dos meus apps. Obviamente, os detalhes do script serão diferentes para seu aplicativo.

 var target = UIATarget.localTarget(); var app = target.frontMostApp(); var window = app.mainWindow(); var picker = window.pickers()[0]; var wheel = picker.wheels()[2]; var buttons = window.buttons(); var button1 = buttons.firstWithPredicate("name == 'dateButton1'"); var button2 = buttons.firstWithPredicate("name == 'dateButton2'"); function setYear(picker, year) { var yearName = year.toString(); var yearWheel = picker.wheels()[2]; yearWheel.selectValue(yearName); } function setMonth(picker, monthName) { var wheel = picker.wheels()[0]; wheel.selectValue(monthName); } function setDay(picker, day) { var wheel = picker.wheels()[1]; var name = day.toString(); wheel.selectValue(name); } target.delay(1); setYear(picker, 2015); setMonth(picker, "July"); setDay(picker, 4); button1.tap(); setYear(picker, 2015); setMonth(picker, "December"); setDay(picker, 25); target.captureScreenWithName("daysShot1"); var nButtons = buttons.length; UIALogger.logMessage(nButtons + " buttons"); for (var i=0; i 

Duas opções disponíveis no site abaixo:

OPÇÃO 1: usando UIWindow (tentou e funciona perfeitamente)

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

OPÇÃO 2: usando o 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(); 

Para canvas retina (como resposta DenNukem)

 // 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()]; } 

para mais detalhes: http://pinkstone.co.uk/how-to-take-a-screeshot-in-ios-programmatically/

Apenas uma pequena contribuição, eu fiz isso com um botão, mas a pressão também significa que o botão é capturado pressionado. Então, primeiro eu não percebo.

 - (IBAction)screenShot:(id)sender { // Unpress screen shot button screenShotButton.highlighted = NO; // create graphics context with screen size CGRect screenRect = [[UIScreen mainScreen] bounds]; if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale); } else { UIGraphicsBeginImageContext(self.view.bounds.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(); // save screengrab to Camera Roll UIImageWriteToSavedPhotosAlbum(screengrab, nil, nil, nil); } 

Eu tenho o corpo principal do código de: http://pinkstone.co.uk/how-to-take-a-screeshot-in-ios-programmatically/ onde eu usei a opção 1, opção 2 não parece funcionar para mim. Adicionado os ajustes para tamanhos de canvas Rentina deste segmento e o destaque do screenShotButton. A visão que estou usando é uma canvas StoryBoarded de botões e labels e com vários UIView adicionados posteriormente através do programa.

No Swift você pode usar o seguinte código.

 if UIScreen.mainScreen().respondsToSelector(Selector("scale")) { UIGraphicsBeginImageContextWithOptions(self.window!.bounds.size, false, UIScreen.mainScreen().scale) } else{ UIGraphicsBeginImageContext(self.window!.bounds.size) } self.window?.layer.renderInContext(UIGraphicsGetCurrentContext()) var image : UIImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil) 

Obter captura de canvas da vista:

 - (UIImage *)takeSnapshotView { CGRect rect = [myView bounds];//Here you can change your view with myView UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); [myView.layer renderInContext:context]; UIImage *capturedScreen = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return capturedScreen;//capturedScreen is the image of your view } 

Espero que isso seja o que você está procurando. Qualquer preocupação voltar para mim. 🙂

Swift 4:

 func makeImage(withView view: UIView) -> UIImage? { let rect = view.bounds UIGraphicsBeginImageContextWithOptions(rect.size, true, 0) guard let context = UIGraphicsGetCurrentContext() else { assertionFailure() return nil } view.layer.render(in: context) guard let image = UIGraphicsGetImageFromCurrentImageContext() else { assertionFailure() return nil } UIGraphicsEndImageContext() return image }