【问题标题】:ios how to capture a particular portion of screenios如何捕获屏幕的特定部分
【发布时间】:2011-12-16 10:53:15
【问题描述】:

我想捕捉 iPhone 屏幕的特定部分。我使用了UIGraphicsBeginImageContextWithOptions,但无法用它捕获屏幕的一部分。 请帮帮我。

【问题讨论】:

  • 您想从您的机器上截取屏幕截图,或者您想通过代码截取应用中的某个区域?
  • @mAc 显然他想用代码来做......如果不是他为什么使用 UIGraphicsBeginImageContextWithOptions

标签: iphone ios screen capture


【解决方案1】:

您可以使用UIGraphicsGetImageFromCurrentContext 进行屏幕截图。从内存中编写了以下代码,因此可能会出错。请自行更正。

- (UIImage*)captureView:(UIView *)yourView {
    CGRect rect = [[UIScreen mainScreen] bounds];
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [yourView.layer renderInContext:context];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

【讨论】:

    【解决方案2】:

    您可以使用此代码

    UIGraphicsBeginImageContext(self.view.bounds.size);
    
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    CGRect rect = CGRectMake(250,61 ,410, 255);
    CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
    
    UIImage *img = [UIImage imageWithCGImage:imageRef]; 
    
    UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil); 
    
    CGImageRelease(imageRef);
    

    【讨论】:

    • 这在您必须捕获屏幕的特定区域时很有用。
    • 我得到了这个特定的部分。但在某些观点中,它隐藏了它的内容。你能说出为什么会这样吗?
    • 仅供未来 Google 员工参考:此代码不考虑屏幕比例
    【解决方案3】:

    另一种捕捉清晰截图的方法;

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
                UIGraphicsBeginImageContextWithOptions(self.captureView.frame.size, NO, [UIScreen mainScreen].scale);
            else
                UIGraphicsBeginImageContext(self.captureView.frame.size);
    
            [self.captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
            UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
            [viewImage drawInRect:CGRectMake(0.0, 0.0, 640,960)];
            //NSData*m_Imgdata=UIImagePNGRepresentation(viewImage);
            NSData*m_Imgdata=UIImageJPEGRepresentation(viewImage, 1.0);
    
           // UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
    
            UIGraphicsEndImageContext();
    

    【讨论】:

      【解决方案4】:

      @Superdev 的答案是正确的,如果您想捕获父视图并避免子视图(特别是覆盖视图),我想添加的是一个小技巧,您可以做的是让这个子视图成为一个属性和使用以下

      CGFloat width = CGRectGetWidth(self.view.bounds);
      CGFloat height = CGRectGetHeight(self.view.bounds);
      _overlayView.hidden = YES;
      UIGraphicsBeginImageContext(self.view.bounds.size);
      
      [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
      
      UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
      
      UIGraphicsEndImageContext();
      
      CGRect rect = CGRectMake(0,0 ,width, height);
      CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
      
      UIImage *img = [UIImage imageWithCGImage:imageRef];
      
      UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
      
      CGImageRelease(imageRef);
      
      _overlayView.hidden = NO;
      

      这是一个小技巧,希望有人会发现它有用

      【讨论】:

        【解决方案5】:

        这是UIView 上的一个快速扩展,它将捕获整个视图或视图中的一个框架。它考虑了屏幕比例。

        extension UIView {
        
            func imageSnapshot() -> UIImage {
                return self.imageSnapshotCroppedToFrame(nil)
            }
        
            func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
                let scaleFactor = UIScreen.mainScreen().scale
                UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
                self.drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
                var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
        
                if let frame = frame {
                    // UIImages are measured in points, but CGImages are measured in pixels
                    let scaledRect = CGRectApplyAffineTransform(frame, CGAffineTransformMakeScale(scaleFactor, scaleFactor))
        
                    if let imageRef = CGImageCreateWithImageInRect(image.CGImage, scaledRect) {
                        image = UIImage(CGImage: imageRef)
                    }
                }
                return image
            }
        }
        

        【讨论】:

        • 嗨,jDutton。我喜欢你的回答。决定为 Swift 3.0 更新您的代码。
        • 非常感谢!!
        【解决方案6】:

        SWIFT 3.0 Xcode8 版本 来自@jDutton 回答并为我工作。

        extension UIView {
            func imageSnapshot() -> UIImage {
                return self.imageSnapshotCroppedToFrame(frame: nil)
            }
        
            func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
                let scaleFactor = UIScreen.main.scale
                UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
                self.drawHierarchy(in: bounds, afterScreenUpdates: true)
                var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
                UIGraphicsEndImageContext()
        
                if let frame = frame {
                    // UIImages are measured in points, but CGImages are measured in pixels
                    let scaledRect = frame.applying(CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
        
                    if let imageRef = image.cgImage!.cropping(to: scaledRect) {
                        image = UIImage(cgImage: imageRef)
                    }
                }
                return image
            }
        }
        

        如果您崩溃并收到以下消息:

        GContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
        CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
        

        试试这个solution

        希望能节省您的时间!

        【讨论】:

          猜你喜欢
          • 2016-02-13
          • 2020-10-28
          • 1970-01-01
          • 2012-05-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-28
          • 1970-01-01
          相关资源
          最近更新 更多