在iOS中如何以编程方式进行屏幕截图?

9
我有一个使用了UIKit控件和OpenGLUIView视图,我想通过程序获取该视图的截图。
如果我使用UIGraphicsGetImageFromCurrentImageContext()方法,OpenGL内容为空白; 如果我使用glReadPixels(...)方法,UIKit内容为空白;
我很困惑如何获取完整的屏幕截图。 谢谢!
8个回答

8
使用以下代码进行屏幕截图:
    -(UIImage *) screenshot
     {

          CGRect rect;
          rect=CGRectMake(0, 0, 320, 480);
          UIGraphicsBeginImageContext(rect.size);

          CGContextRef context=UIGraphicsGetCurrentContext();
          [self.view.layer renderInContext:context];

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

          return image;
     }

1
这段代码只是为了获取UIKit的内容...问题更加复杂且解释得很好:他还需要获取OpenGL的内容。 - Matteo Gobbi

5
-(UIImage *) screenshot
{
CGImageRef UIGetScreenImage(void);
CGImageRef screen = UIGetScreenImage();
UIImage* screenImage = [UIImage imageWithCGImage:screen];
CGImageRelease(screen); // you need to call this.
return screenImage;
}

有人能解释一下它是如何工作的吗?还需要修正方向。 - ZYiOS
这绝对不是正确的方法,原因在于 - Julian

5

嗯,有几种方法可以通过编程方式捕获iPhone屏幕

  1. Using UIKIT http://developer.apple.com/library/ios/#qa/qa1703/_index.html

  2. Using AVFoundation framework http://developer.apple.com/library/ios/#qa/qa1702/_index.html

  3. Using OpenGL ES http://developer.apple.com/library/ios/#qa/qa1704/_index.html

  4. Starting from iOS 7 you can also use Why does my programmatically created screenshot look so bad on iOS 7?

  5. Using UIWindow

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    UIGraphicsBeginImageContext(screenRect.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor blackColor] set];
    CGContextFillRect(ctx, screenRect);
    [self.window.layer renderInContext:ctx];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
  6. Using UIView

    UIGraphicsBeginImageContext(self.view.frame.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

在这6个选项中,我发现第一个选项非常方便复制和应用压缩级别,因为第一种方法能够给出真实的像素数据。我也喜欢第四个选项,因为该API带有SDK。


1
谢谢您,似乎带有子视图控制器的屏幕不会自动添加子视图控制器层。但是使用窗口似乎可以用于全屏图像。谢谢! - slycrel

2
您可以获得UIImage的结果,而不会丢失图像质量。
    - (UIImage *)captureView:(UIView *)view {
     UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
     [view.layer renderInContext:UIGraphicsGetCurrentContext()];
     UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
     UIGraphicsEndImageContext();
     return img;
     }

它在OpenGL页面中没有产生效果。 - coodi8

1
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = [UIImagePNGRepresentation(image) retain];
UImage *screenShot = [UIImage imageWithData:data];

它只在UIKit条件下生效,对于OpenGL页面,只能获得空白图像。 - coodi8

0

以下是如何以编程方式获取UIImage的简单屏幕截图。如果您想要对其他对象进行替换,请将UIImage替换为它。

.h文件中添加NSData *Data;,然后在您的.m文件中将其添加到您的代码中。

UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *attachimage = [[UIImage alloc]initWithData:Data];
UIImage *viImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
attachimage = viImage;
UIImageWriteToSavedPhotosAlbum(viImage, nil, nil, nil);

它只在UIKit条件下生效,对于OpenGL页面,只能获取空白图像。 - coodi8

0

你知道OpenGL内容在你的视图中的位置。因此,将glReadPixels的结果复制到UIKit的快照中应该很容易。


我正在开发一个截屏控件,但我不知道这个视图是由UIKit还是OpenGL实现的,或者是混合的。如果我能获取到视图是由什么实现的信息,问题就会得到解决。 - coodi8
@coodi8 我认为这可能是一个问题。这不会很容易,因为OpenGL直接在图形芯片上进行渲染。UI图形不是在图形芯片上渲染的。(据我所知) - Felix K.

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接