【问题标题】:how to take a screenshot of the iPhone programmatically?如何以编程方式截取 iPhone 的屏幕截图?
【发布时间】:2011-04-06 08:28:08
【问题描述】:

是否有可能在Objective C中我们可以截取屏幕截图并将此图像存储在UIImage中。

【问题讨论】:

标签: iphone objective-c cocoa-touch


【解决方案1】:

是的,这是 Apple 开发者论坛的链接 https://devforums.apple.com/message/149553

【讨论】:

    【解决方案2】:

    您需要创建屏幕大小的位图上下文并使用

    [self.view.layer renderInContext:c]
    

    在其中复制您的视图。完成后,您可以使用

    CGBitmapContextCreateImage(c)
    

    从您的上下文创建一个 CGImage。

    阐述:

    CGSize screenSize = [[UIScreen mainScreen] applicationFrame].size;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef ctx = CGBitmapContextCreate(nil, screenSize.width, screenSize.height, 8, 4*(int)screenSize.width, colorSpaceRef, kCGImageAlphaPremultipliedLast);
    CGContextTranslateCTM(ctx, 0.0, screenSize.height);
    CGContextScaleCTM(ctx, 1.0, -1.0);
    
    [(CALayer*)self.view.layer renderInContext:ctx];
    
    CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
    UIImage *image = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    CGContextRelease(ctx);  
    [UIImageJPEGRepresentation(image, 1.0) writeToFile:@"screen.jpg" atomically:NO];
    

    请注意,如果您运行代码以响应对 UIButton 的点击,您的图像将显示该按钮被按下。

    【讨论】:

    • 你能详细说明一下吗?谢谢
    • 只是想提一下你错过了释放 colorSpaceRef
    • 另外,self 是什么?那么窗口变换呢?您知道显示键盘/警报时会发生什么吗?
    【解决方案3】:

    前面的代码假定要捕获的视图位于主屏幕上……它可能不会。

    这是否可以始终捕获主窗口的内容? (警告:在 StackOverflow 中编译)

    
    - (UIImage *) captureScreen {
        UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
        CGRect rect = [keyWindow bounds];
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [keyWindow.layer renderInContext:context];   
        UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return img;
    }
    

    【讨论】:

    • 我在视图中为图形设置动画,但此代码忽略了动画(完成后未删除)
    • 谢谢!这是迄今为止我发现的最简单的方法。
    • 那不行:状态栏没有保存,我的一个视图是 OpenGL 视图,它的内容也没有保存。
    【解决方案4】:

    技术问答QA1703 UIKit 应用程序中的屏幕截图

    http://developer.apple.com/iphone/library/qa/qa2010/qa1703.html

    【讨论】:

    • 感谢。+1 提供苹果资源。
    • 链接断开:-(
    【解决方案5】:

    试试这个……

    - (UIImage*)captureView:(UIView *)view 
    {
        CGRect rect = [[UIScreen mainScreen] bounds];
        UIGraphicsBeginImageContext(rect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();
        [view.layer renderInContext:context];
        UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return img;
    }
    
    - (void)saveScreenshotToPhotosAlbum:(UIView *)view 
    {
        UIImageWriteToSavedPhotosAlbum([self captureView:self.view], nil, nil,nil);
    }
    

    【讨论】:

      【解决方案6】:

      使用此代码截取屏幕截图:

      -(void)webViewDidFinishLoad:(UIWebView *)webView
      {
      UIGraphicsBeginImageContext(self.webView.bounds.size);
      
          [self.webView.layer renderInContext:UIGraphicsGetCurrentContext()];
      
          UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
      
          UIGraphicsEndImageContext();
      
          UIImageWriteToSavedPhotosAlbum(screenshotImage, nil, nil, nil);
      
          NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
      
      
          NSString *str1=[NSString stringWithFormat:@"%d",myInt];
      
          NSString *pngFilePath = [NSString stringWithFormat:@"%@/page_%@.png",docDir,str1]; // any name u want for image
          NSLog(@"%@",pngFilePath);
          NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(screenshotImage)]; 
          [data1 writeToFile:pngFilePath atomically:YES];
      }
      

      【讨论】:

      • 你需要什么data1, UIImagePNGRepresentation 已经是NSData了
      【解决方案7】:
      UIGraphicsBeginImageContext(self.window.bounds.size);
      [self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      NSData * data = UIImagePNGRepresentation(image);
      [data writeToFile:@"foo.png" atomically:YES];
      

      2011 年 4 月更新:对于视网膜显示,将第一行更改为:

      if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
      {
          UIGraphicsBeginImageContextWithOptions(self.window.bounds.size, NO, [UIScreen mainScreen].scale);
      }
      else
      {
          UIGraphicsBeginImageContext(self.window.bounds.size);
      }
      

      【讨论】:

        【解决方案8】:
        - (void)SnapShot {
            if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
                UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
            } else {
                UIGraphicsBeginImageContext(self.view.bounds.size);
            }
            [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
        
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
        
            NSData *data = UIImagePNGRepresentation(image);
            [data writeToFile:@"snapshot.png" options:NSDataWritingWithoutOverwriting error:Nil];
            [data writeToFile:@"snapshot.png" atomically:YES];
        
            UIImageWriteToSavedPhotosAlbum([UIImage imageWithData:data], nil, nil, nil);
        }
        

        【讨论】:

        • 1.你有双重写入文件。 2. 如果上面已经有图片对象,为什么还需要[UIImage imageWithData:data]。 3.骆驼案
        【解决方案9】:
        • (UIImage *)截图 { UIGraphicsBeginImageContextWithOptions(self.main_uiview.bounds.size, NO, 2.0f); [self.main_uiview drawViewHierarchyInRect:_main_uiview.bounds afterScreenUpdates:YES];

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

          返回图片; }

        【讨论】:

          【解决方案10】:

          // 100% 工作

          - (UIImage *)screenshot
          {                   
            UIGraphicsBeginImageContextWithOptions(self.main_uiview.bounds.size, NO, 2.0f);
            [self.main_uiview drawViewHierarchyInRect:_main_uiview.bounds afterScreenUpdates:YES];
          
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
          
            return image;
          }
          

          【讨论】:

            【解决方案11】:

            以现代方式:

            Obj-C

            @interface UIView (Snapshot)
            - (UIImage * _Nullable)snapshot;
            @end
            
            @implementation UIView (Snapshot)
            
            - (UIImage * _Nullable)snapshot {
                UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, UIScreen.mainScreen.scale);
                [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
                UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
                return image;
            }
            
            @end
            

            斯威夫特

            extension UIView {
                func snapshot() -> UIImage? {
                    UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
                    drawHierarchy(in: bounds, afterScreenUpdates: true)
                    let image = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()
                    return image
               }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-03-18
              • 2011-01-13
              相关资源
              最近更新 更多