如何以编程方式获取屏幕截图

我想在保存到保存的照片库的屏幕上的图像的屏幕截图

考虑检查视网膜显示使用以下代码片段:

#import <QuartzCore/QuartzCore.h> 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"); } 

下面的方法也适用于OPENGL对象

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

来源 。

看到这个post,看起来你现在可以使用UIGetScreenImage()。

在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 } 

这将节省屏幕截图,并返回截图。

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

Swift 3实现我找不到答案。 所以在这里。

 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 } 

我认为如果你想全屏( 状态栏除外 ),下面的代码会有帮助,如果需要的话,用你的应用程序委托名replaceAppDelegate。

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

从视图获取屏幕截图

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

将图像保存到照片

 UIImageWriteToSavedPhotosAlbum(YOUR_IMAGE, nil, nil, nil); 

如何

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

对于iOS 7.0或更高版本

如果你想截取视图说(myView),你可以用单行来做到这一点:

 [myView snapshotViewAfterScreenUpdates:NO]; 

从iOS10开始,这变得更简单了。 UIKit附带UIGraphicsImageRender ,允许你

…完成绘图任务,无需处理configuration(如颜色深度和图像比例),或者pipe理Core Graphics上下文

Apple Docs – UIGraphicsImageRenderer

所以你现在可以做这样的事情:

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

这里的许多答案在大多数情况下适用于我。 但是,当试图拍摄一个ARSCNView的快照时,我只能用上面描述的方法做到这一点。 虽然可能值得注意的是,在这个时候,ARKit仍然处于testing阶段,Xcode处于testing阶段

另一种select是在仪器上使用自动化工具。 你写一个脚本把屏幕变成任何你想要的状态,然后进行拍摄。 这是我用于我的一个应用程序的脚本。 很明显,对于你的应用程序,脚本的细节将会有所不同。

 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<nButtons; i++) { UIALogger.logMessage("button " + buttons[i].name()); } var tabBar = window.tabBars()[0]; var barButtons = tabBar.buttons(); var nBarButtons = barButtons.length; UIALogger.logMessage(nBarButtons + " buttons on tab bar"); for (var i=0; i<nBarButtons; i++) { UIALogger.logMessage("button " + barButtons[i].name()); } var weeksButton = barButtons[1]; var monthsButton = barButtons[2]; var yearsButton = barButtons[3]; target.delay(2); weeksButton.tap(); target.captureScreenWithName("daysShot2"); target.delay(2); monthsButton.tap(); target.captureScreenWithName("daysShot3"); target.delay(2); yearsButton.tap(); target.delay(2); button2.tap(); target.delay(2); setYear(picker, 2018); target.delay(2); target.captureScreenWithName("daysShot4"); 

波纹pipe现场提供两种select:

选项1:使用UIWindow(尝试完美)

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

选项2:使用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(); 

对于视网膜屏幕(如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()]; } 

更多细节: http : //pinkstone.co.uk/how-to-take-a-screeshot-in-ios-programmatically/

只是一个小小的贡献,我已经做了这个button,但按下也意味着button被捕获按下。 所以我首先不高兴。

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

我得到了代码的主体: http : //pinkstone.co.uk/how-to-take-a-screeshot-in-ios-programmatically/我在哪里使用了选项1,选项2似乎没有工作为了我。 从这个线程添加了对Rentina屏幕大小的调整,以及screenShotButton的高亮度调整。 我使用的视图是一个StoryBoardedbutton和标签的屏幕,以及稍后通过该程序添加的几个UIView。

在Swift中你可以使用下面的代码。

 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) 

从视图获取屏幕截图:

 - (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 } 

希望,这是你要找的。 任何关心回到我身边。 🙂

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 }