私は見つけました このコード :
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)
}
ナビゲーションバーなどの他のすべての要素をスクリーンショットに取り込むには、何をする必要がありますか?
ただ答えをそこに投げるのではなく、現在のコードが何をするのか、それを変更して全画面をキャプチャする方法を説明しましょう。
UIGraphicsBeginImageContext(view.frame.size)
このコード行は、view
と同じサイズの新しい画像コンテキストを作成します。ここで取り上げる主なことは、新しいイメージコンテキストがview
と同じサイズであることです。アプリケーションの低解像度(非網膜)バージョンをキャプチャする場合を除き、代わりにUIGraphicsBeginImageContextWithOptions
を使用する必要があります。次に、0.0
を渡して、デバイスのメイン画面と同じスケール係数を取得できます。
view.layer.renderInContext(UIGraphicsGetCurrentContext())
このコード行は、ビューのレイヤーを現在のグラフィックスコンテキスト(作成したばかりのコンテキスト)にレンダリングします。ここで取り上げる主なことは、view
(およびそのサブビュー)のみが画像コンテキストに描画されることです。
let image = UIGraphicsGetImageFromCurrentImageContext()
このコード行は、グラフィックコンテキストに描画されたものからUIImageオブジェクトを作成します。
UIGraphicsEndImageContext()
このコード行は、イメージコンテキストを終了します。クリーンアップです(コンテキストを作成し、同様に削除する必要があります。
結果は、view
と同じサイズの画像に、view
とそのサブビューが描画されます。
すべてを画像に描画する場合は、画面のサイズの画像を作成し、画面上にあるすべての画像を描画する必要があります。実際には、アプリケーションの「キーウィンドウ」内のすべてについて話しているだけです。 UIWindow
はUIView
のサブクラスであるため、画像コンテキストにも描画できます。
Swift 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
}
Swift 2用に更新
指定したコードは機能しますが、スクリーンショットでNavigationBar
とStatusBar
をキャプチャすることはできません。 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)
}
このコードでは:
StatusBar
は最終画像には表示されません。IOSでテスト済み:9、10、11、12
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)
}
}
imageView.image = UIApplication.shared.makeSnapshot()
// or
imageView.image = view.makeSnapshot()
// or
imageView.image = view.layer.makeSnapshot()
// or
imageView.image = UIImage(snapshotOf: view)
Xcode 8.2.1、Swift 3
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
}
}
iOS 9xのバージョン1コードを使用しようとすると、エラーが発生します:CGImageCreateWithImageProvider:無効な画像プロバイダー: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
}
}
let screenShot = UIApplication.shared.screenShot!
Swift 3の例:
func captureScreen() -> UIImage? {
guard let context = UIGraphicsGetCurrentContext() else { return .none }
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.main.scale)
view.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
簡単にするために、独自のファイルに拡張子を追加します
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
}
}
次のように拡張機能を呼び出します...
let window: UIWindow! = UIApplication.sharedApplication().keyWindow
let windowImage = window.capture()
同様に、UIViewを拡張してその画像をキャプチャすることもできます。
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
}
}
私はこの方法を使用します:
func captureScreen() -> UIImage {
var window: UIWindow? = UIApplication.sharedApplication().keyWindow
window = UIApplication.sharedApplication().windows[0] as? UIWindow
UIGraphicsBeginImageContextWithOptions(window!.frame.size, window!.opaque, 0.0)
window!.layer.renderInContext(UIGraphicsGetCurrentContext())
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image;
}
ステータスバーを除くすべてをキャプチャし、カメラロールに画像を保存する許可を求めません。
それが役に立てば幸い!
IWindowのSwift 3拡張
public extension UIWindow {
func capture() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(self.frame.size, self.isOpaque, UIScreen.main.scale)
self.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}]
これは似ていますが、将来的に誰かの助けになることを願っています。
self.view.image() //returns UIImage
これがSwift 3ソリューションです
https://Gist.github.com/nitrag/b3117a4b6b8e89fdbc12b98029cf98f8
// Full Screen Shot function. Hope this will work well in Swift.
func screenShot() -> UIImage {
UIGraphicsBeginImageContext(CGSizeMake(frame.size.width, frame.size.height))
var context:CGContextRef = UIGraphicsGetCurrentContext()
self.view?.drawViewHierarchyInRect(frame, afterScreenUpdates: true)
var screenShot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return screenShot
}
私のバージョンもキーボードをキャプチャします。 Swift 4.2
extension UIApplication {
var screenshot: UIImage? {
UIGraphicsBeginImageContextWithOptions(UIScreen.main.bounds.size, false, 0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
for window in windows {
window.layer.render(in: context)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
view.snapshotView(afterScreenUpdates:true)
これは私がSwift 4でそれを行う方法です
let layer = UIApplication.shared.keyWindow!.layer
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
スクリーンショットはUIImageタイプになります
Swift 4以上
拡張のため、キャプチャするUIViewによる呼び出し。
宣言
extension UIView {
func viewCapture() -> UIImage? {
UIGraphicsBeginImageContext(self.frame.size)
guard let cgContext = UIGraphicsGetCurrentContext() else {
print("Fail to get CGContext")
return nil
}
self.layer.render(in: cgContext)
guard let image = UIGraphicsGetImageFromCurrentImageContext() else {
print("Fail to get Image from current image context")
return nil
}
UIGraphicsEndImageContext()
return image
}
}
使用法
var m_image = UIImage()
if let tempCaptureImg = self.m_Capture_View.viewCapture() {
viewController.m_image = tempCaptureImg
}
// m_Capture_ViewはUIViewのタイプです