拍摄带有背景图片的屏幕截图-iOS

时间:2019-03-06 04:23:44

标签: ios swift uiview uikit uigraphicscontext

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

我认为问题在于clearContainerView仅包含文本,而不包含图像。我不能将图像放在clearContainerView内,因为我希望图像可以延伸到整个屏幕...而且我希望文本位于标题和标签栏之间(如上方的绿色方框所示)。

我的代码和图片如下:

这是我当前在Storyboard中的布局: enter image description here

这是我想要的屏幕截图: enter image description here

这是我得到的屏幕截图: enter image description here

这是我的代码:

@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
    }
}

有关如何执行此操作的任何建议?

6 个答案:

答案 0 :(得分:1)

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

resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets:

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

我尝试了以下方法。

我的原始视图。

enter image description here

屏幕截图

enter image description here

答案 1 :(得分:0)

主要代码:

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
    }

}

输出: enter image description here

截图后: enter image description here

我所做的:使用您的方法拍摄整个视图的屏幕截图,然后通过将CGPoints转换为像素来裁剪图像。

答案 2 :(得分:0)

您可以使用下面给出的代码捕获屏幕截图。它将捕获整个窗口而不是特定视图。但是请注意,如果您不希望屏幕截图中的“标题”,“按钮”和“标签栏”,那么您需要将其隐藏在UIGraphicsBeginImageContextWithOptions之前,然后在{{1之后}}。

UIGraphicsEndImageContext

答案 3 :(得分:0)

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

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

正如您所言,如果图像位于clearContainerView之外

enter image description here

代码

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)
        }
    }
}

输出:

enter image description here

答案 4 :(得分:0)

试试看! 辅助功能

filter

调用

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
    }
}

ImageView(清除容器视图)是您要快照屏幕的视图。您可以将其更改为uiview或任何view。 希望有帮助。

答案 5 :(得分:0)

使用此扩展名。

//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)
    }

}