[英]How to take a screenshot programmatically on iOS
我想在屏幕上保存到保存的照片库中的图像截图。
考虑检查视网膜显示,请使用以下代码段:
#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);
}
来源 。
看到这篇文章看起来你现在可以使用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
}
从iOS10开始,这会变得更简单一些。 UIKit附带UIGraphicsImageRender
,可以让你
...完成绘图任务,无需处理颜色深度和图像比例等配置,或管理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仍处于测试阶段且Xcode处于测试版4
这将保存屏幕截图并返回屏幕截图。
-(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;
}
我认为如果您想要全屏( 状态栏除外 ),以下代码段会有所帮助,如果需要,只需将AppDelegate替换为您的应用代理名称即可。
- (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;
}
我找不到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
}
适用于iOS 7.0或更高版本..
如果你想截取视图说明(myView),你可以用单行做到这一点:
[myView snapshotViewAfterScreenUpdates:NO];
从视图获取屏幕截图
-(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);
从视图获取屏幕截图:
- (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.2 ,截图将保存在库中,但请不要忘记编辑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)
}
另一种选择是在仪器上使用自动化工具。 你编写一个脚本将屏幕放入你想要的任何状态,然后拍摄。 这是我用于其中一个应用程序的脚本。 显然,脚本的细节会因您的应用而异。
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");
只是一个小小的贡献,我用按钮做了这个,但按下也意味着按下按钮。 所以首先我不亮。
- (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的不突出显示。 我正在使用它的视图是一个按钮和标签的StoryBoarded屏幕,稍后通过该程序添加了几个UIView。
波纹管网站提供两种选择:
选项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/
在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)
斯威夫特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
}
我正在回答这个问题,因为它是一个受到高度关注的问题,并且有许多答案,还有Swift和Obj-C。
免责声明 这不是我的代码, 也不是我的答案, 这只是为了帮助那里的人找到快速答案。 有信用到期的原始答案的链接给予信贷! 如果您使用他们的答案,请尊重+1!
#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");
}
func captureScreen() -> UIImage
{
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, 0);
self.view.drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
注意: 由于编程的性质, 可能需要更新,所以请编辑或让我知道! *此外,如果我没有包括一个值得的答案/方法,请随时告诉我!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.