如何在Swift中使用全屏截图?

Pie*_*ada 64 screenshot uiimage ios swift

我发现了这段代码:

func screenShotMethod() {
    //Create the UIImage
    UIGraphicsBeginImageContext(view.frame.size)
    view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    //Save it to the camera roll
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}
Run Code Online (Sandbox Code Playgroud)

我需要做些什么才能将所有其他元素(如导航栏)添加到屏幕截图中?

Dav*_*ist 72

让我解释一下当前代码的作用以及如何修改它以捕获全屏,而不仅仅是在那里抛出答案.

UIGraphicsBeginImageContext(view.frame.size)
Run Code Online (Sandbox Code Playgroud)

这行代码创建了一个与之相同大小的新图像上下文view.这里要带走的主要是新图像上下文的大小相同view.除非您想要捕获应用程序的低分辨率(非视网膜)版本,否则您应该使用它UIGraphicsBeginImageContextWithOptions.然后您可以传递0.0以获得与设备主屏幕相同的比例因子.

view.layer.renderInContext(UIGraphicsGetCurrentContext())
Run Code Online (Sandbox Code Playgroud)

这行代码将视图的图层渲染到当前图形上下文(这是您刚刚创建的上下文).这里要取消的主要内容是只有view(及其子视图)被绘制到图像上下文中.

let image = UIGraphicsGetImageFromCurrentImageContext()
Run Code Online (Sandbox Code Playgroud)

这行代码从绘制到图形上下文中的内容创建UIImage对象.

UIGraphicsEndImageContext()
Run Code Online (Sandbox Code Playgroud)

这行代码结束了图像上下文.它是清理的(你创建了上下文,也应该删除它.


其结果是,其大小与相同的图像view,用view和它的子视图吸入到它.

如果要将所有内容绘制到图像中,则应创建一个与屏幕大小相同的图像,并将屏幕上的所有内容绘制到其中.实际上,您可能只是在谈论应用程序"关键窗口"中的所有内容.由于UIWindow是子类UIView,因此也可以将其绘制到图像上下文中.


Ima*_*tit 58

斯威夫特4

    /// Takes the screenshot of the screen and returns the corresponding image
    ///
    /// - Parameter shouldSave: Boolean flag asking if the image needs to be saved to user's photo library. Default set to 'true'
    /// - Returns: (Optional)image captured as a screenshot
    open func takeScreenshot(_ shouldSave: Bool = true) -> UIImage? {
        var screenshotImage :UIImage?
        let layer = UIApplication.shared.keyWindow!.layer
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        layer.render(in:context)
        screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let image = screenshotImage, shouldSave {
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        }
        return screenshotImage
    }
Run Code Online (Sandbox Code Playgroud)

更新了Swift 2

你的代码提供的作品,但不会让你捕捉NavigationBarStatusBar您的屏幕截图.如果您想截取包含该设备的设备的屏幕截图,则NavigationBar必须使用以下代码:

func screenShotMethod() {
    let layer = UIApplication.sharedApplication().keyWindow!.layer
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

    layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}
Run Code Online (Sandbox Code Playgroud)

使用此代码:

  • 第一次启动应用程序并调用此方法时,iOS设备将询问您是否允许将图像保存在相机胶卷中.
  • 此代码的结果将是.JPG图像.
  • StatusBar不会出现在最终的影像中.

  • 好方法!由于比例尺,它以完整的视网膜分辨率捕获图像.非常感谢这段代码!Yan- (3认同)

Vas*_*huk 25

细节

Xcode 9.3,Swift 4.1

在iOS上测试:9,10,11

import UIKit

extension UIApplication { func makeSnapshot() -> UIImage? { return keyWindow?.layer.makeSnapshot() } }

extension CALayer {
    func makeSnapshot() -> UIImage? {
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(frame.size, false, scale)
        defer { UIGraphicsEndImageContext() }
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        render(in: context)
        let screenshot = UIGraphicsGetImageFromCurrentImageContext()
        return screenshot
    }
}

extension UIView {
    func makeSnapshot() -> UIImage? {
        if #available(iOS 10.0, *) {
            let renderer = UIGraphicsImageRenderer(size: frame.size)
            return renderer.image { _ in drawHierarchy(in: bounds, afterScreenUpdates: true) }
        } else {
            return layer.makeSnapshot()
        }
    }
}

extension UIImage {
    convenience init?(snapshotOf view: UIView) {
        guard let image = view.makeSnapshot(), let cgImage = image.cgImage else { return nil }
        self.init(cgImage: cgImage, scale: image.scale, orientation: image.imageOrientation)
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

imageView.image = UIApplication.shared.makeSnapshot()

// or
imageView.image = view.makeSnapshot()

// or
imageView.image = view.layer.makeSnapshot()

// or
imageView.image = UIImage(snapshotOf: view)
Run Code Online (Sandbox Code Playgroud)

细节

Xcode 8.2.1,swift 3

适用于iOS 10x的版本1

import UIKit

extension UIApplication {

    var screenShot: UIImage?  {

        if let layer = keyWindow?.layer {
            let scale = UIScreen.main.scale

            UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
            if let context = UIGraphicsGetCurrentContext() {
                layer.render(in: context)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

适用于iOS 9x的版本2,10x

如果您将尝试在iOS 9x中使用版本1代码, 则会出现错误:CGImageCreateWithImageProvider:invalid image provider:NULL.

import UIKit

extension UIApplication {

    var screenShot: UIImage?  {

        if let rootViewController = keyWindow?.rootViewController {
            let scale = UIScreen.main.scale
            let bounds = rootViewController.view.bounds
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale);
            if let _ = UIGraphicsGetCurrentContext() {
                rootViewController.view.drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

let screenShot = UIApplication.shared.screenShot!
Run Code Online (Sandbox Code Playgroud)


Dan*_*orm 23

Swift 3示例:

extension UIImage {

    convenience init?(view: UIView?) {
        guard let view: UIView = view else { return nil }

        UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
        guard let context: CGContext = UIGraphicsGetCurrentContext() else {
            UIGraphicsEndImageContext()
            return nil
        }

        view.layer.render(in: context)
        let contextImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        guard
            let image: UIImage = contextImage,
            let pngData: Data = image.pngData()
            else { return nil }

        self.init(data: pngData)
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 这是截取特定视图的屏幕截图,而不是整个屏幕的屏幕截图。 (2认同)

Dam*_*amo 10

为方便起见,我会在它自己的文件中添加一个扩展名

import UIKit

  public extension UIWindow {

    func capture() -> UIImage {

      UIGraphicsBeginImageContextWithOptions(self.frame.size, self.opaque, UIScreen.mainScreen().scale)
      self.layer.renderInContext(UIGraphicsGetCurrentContext()!)
      let image = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()

      return image
  }
}
Run Code Online (Sandbox Code Playgroud)

按如下方式拨打分机号码......

let window: UIWindow! = UIApplication.sharedApplication().keyWindow

let windowImage = window.capture()
Run Code Online (Sandbox Code Playgroud)

同样,人们可以扩展UIView来捕捉那个......


nea*_*ave 5

在 iOS 10 中创建上下文的推荐方法是使用UIGraphicsImageRenderer.

extension UIView {
    func capture() -> UIImage? {
        var image: UIImage?

        if #available(iOS 10.0, *) {
            let format = UIGraphicsImageRendererFormat()
            format.opaque = isOpaque
            let renderer = UIGraphicsImageRenderer(size: frame.size, format: format)
            image = renderer.image { context in
                drawHierarchy(in: frame, afterScreenUpdates: true)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(frame.size, isOpaque, UIScreen.main.scale)
            drawHierarchy(in: frame, afterScreenUpdates: true)
            image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
        }

        return image
    }
}
Run Code Online (Sandbox Code Playgroud)