【问题标题】:Take a screenshot with background image - iOS使用背景图片截取屏幕截图 - iOS
【发布时间】:2019-03-06 04:23:44
【问题描述】:

我想截图。在此屏幕截图中,我想要其中的文本和图像。但是,我遇到了一个问题,因为当我截取屏幕截图时,我只看到文本而看不到图像。

我认为问题在于clearContainerView 只包含文本而不包含图像。我不能将图像放在clearContainerView 中,因为我希望图像能够拉伸整个屏幕......并且我希望文本在标题和标签栏之间居中(如上图绿色方块所示)。

我的代码和图片如下:

这是我目前在 Storyboard 中的布局:

这是我想要的截图:

这是我得到的屏幕截图:

这是我的代码:

@IBOutlet weak var clearContainerView: UIView!

@IBAction func takeScreenshotTapped(_ sender: UIButton) {
    let screenshot = clearContainerView.screenshot()
    print(screenshot)
}

extension UIView {
    func screenshot() -> UIImage {
        let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
            drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
        }

        return image
    }
}

关于如何做到这一点的任何建议?

【问题讨论】:

  • @AshishKakkad 不,背景图像不在名为 clearContainerView 的 UIView 内。请阅读最后一段以获得解释。
  • @AshishKakkad 请再读一遍,这不是重复的。
  • 您需要将该图像放入您的 clearContainer 中。因为您正在拍摄 clearContainer 的快照,而该代码只能捕获 clearContainer 的内容
  • @SahilManchanda 请阅读我的问题,上面写着:“我认为问题在于clearContainerView 仅包含文本而不包含图像。我无法将图像放入clearContainerView因为我希望图像拉伸整个屏幕......并且我希望文本在标题和标签栏之间居中(如上面的绿色方块所示)。”这对你有意义吗?谢谢
  • 我会试一试,让你知道它是否有效

标签: ios swift uiview uikit uigraphicscontext


【解决方案1】:

您可以在控制器视图上使用以下方法来获取 clearContainerView 的一部分,这将是一个快照视图。然后您可以使用该视图对象并对其进行截图。

resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:

您必须传递 rect,这将是您的 clearContainerView 框架。如果您不想要任何可拉伸的内容,您可以传递零插图。它返回一个视图对象,其中将包含您的 imageView 部分 + 您的完整 clearContainerView。然后您可以使用返回的视图并对其进行屏幕截图。

我尝试了以下方法。

我原来的看法。

截图

【讨论】:

  • 太棒了,谢谢!不知道有这个功能
【解决方案2】:

使用这个扩展。

//USAGE



 let image = self.view.snapshot(of:self.<your view>.frame) 

这里的“你的视图”应该是层次结构的基本视图,或者你可以简单地使用

 let image = self.view.snapshot(of:self.view.frame)

扩展

// UIView screenshot
extension UIView {

    /// Create snapshot
    ///
    /// - parameter rect: The `CGRect` of the portion of the view to return. If `nil` (or omitted),
    ///                   return snapshot of the whole view.
    ///
    /// - returns: Returns `UIImage` of the specified portion of the view.

    func snapshot(of rect: CGRect? = nil) -> UIImage? {
        // snapshot entire view

        UIGraphicsBeginImageContextWithOptions(bounds.size,  false, 0.0)
        drawHierarchy(in: bounds, afterScreenUpdates: true)
        let wholeImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        // if no `rect` provided, return image of whole view

        guard let image = wholeImage, let rect = rect else { return wholeImage }

        // otherwise, grab specified `rect` of image

        let scale = image.scale
        let scaledRect = CGRect(x: rect.origin.x * scale, y: rect.origin.y * scale, width: rect.size.width * scale, height: rect.size.height * scale)
        guard let cgImage = image.cgImage?.cropping(to: scaledRect) else { return nil }
        return UIImage(cgImage: cgImage, scale: scale, orientation: .up)
    }

}

【讨论】:

    【解决方案3】:

    主代码:

    let frame = containerView.frame
    let x: CGFloat = 0
    let y = frame.minY.pointsToPixel()
    let width = frame.width.pointsToPixel()
    let height = frame.height.pointsToPixel()
    let rect = CGRect(x: x, y: y, width: width, height: height)
    let image = cropImage(image: view.screenshot(), toRect: rect)
    
    
    extension UIView {
        func screenshot() -> UIImage {
            let image = UIGraphicsImageRenderer(size: bounds.size).image { _ in
                drawHierarchy(in: CGRect(origin: .zero, size: bounds.size), afterScreenUpdates: true)
            }
    
            return image
        }
    }
    public extension CGFloat {
        func pointsToPixel() -> CGFloat {
            return self * UIScreen.main.scale
        }
    
    }
    

    输出:

    截图后:

    我做了什么:用你的方法截取整个视图,然后通过将 CGPoints 转换为像素来裁剪图像。

    【讨论】:

      【解决方案4】:

      您可以使用下面给出的代码来捕获屏幕截图。它将捕获整个窗口而不是特定视图。但是要注意一件事,如果您不想在屏幕截图中显示“标题”、“按钮”和“标签栏”,那么您需要将它们隐藏在 UIGraphicsBeginImageContextWithOptions 之前并在 UIGraphicsEndImageContext 之后再次显示它们。

      func takeScreenshot() -> UIImage? {
              var screenshotImage: UIImage?
              let layer = UIApplication.shared.keyWindow!.layer
              let scale = UIScreen.main.scale
              // Hide your title label, button and tab bar here
              UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
              guard let context = UIGraphicsGetCurrentContext() else {return nil}
              layer.render(in:context)
              screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
              UIGraphicsEndImageContext()
              // Unhide your title label, button and tab bar here
              return screenshotImage
      }
      
      @IBAction func takeScreenshotTapped(_ sender: UIButton) {
          let screenshot = takeScreenshot()
          print(screenshot)
      }
      

      【讨论】:

        【解决方案5】:

        一切都很好。我已经为您的预期输出做了一个演示。

        您只需要像这样更改视图层次结构:

        正如你所说的图片,如果在clearContainerView之外的话

        代码

        class VC: UIViewController {
        
            @IBOutlet weak var mainVw: UIView!
            @IBOutlet weak var clearContainerView: UIView!
        
            override func viewDidLoad() {
                super.viewDidLoad()
            }
        
        
            @IBAction func takeImage(_ sender: Any) {
        
                if let VC_1 = self.storyboard?.instantiateViewController(withIdentifier: "VC1") as? VC1{
                    VC_1.img = mainVw.screenshot()
                    self.present(VC_1, animated: false, completion: nil)
                }
            }
        }
        

        输出:

        【讨论】:

          【解决方案6】:

          试试这个! 辅助函数

          struct UIGraphicsDrawImageHelper {
              static func drawImage(from image: UIImageView) -> UIImage? {
                  UIGraphicsBeginImageContextWithOptions(image.bounds.size, image.isOpaque, 0.0)
                  image.drawHierarchy(in: image.bounds, afterScreenUpdates: false)
                  let renderImage = UIGraphicsGetImageFromCurrentImageContext()
                  UIGraphicsEndImageContext()
                  return renderImage
              }
          }
          

          调用它

          guard let image = UIGraphicsDrawImageHelper.drawImage(from: qrcodeImageView) else { return }
          

          ImageView (Clear Container View) 是您要对屏幕进行快照的视图。您可以将其更改为 uiview 或任何视图。 希望对您有所帮助。

          【讨论】:

            猜你喜欢
            • 2016-02-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-26
            • 1970-01-01
            相关资源
            最近更新 更多