web-dev-qa-db-fra.com

Comment prendre une capture d'écran d'une UIView en swift?

J'ai une UIView nommée overView:

overView.frame = CGRectMake(self.view.frame.width/25, self.view.frame.height/25, self.view.frame.width/1.3, self.view.frame.height/1.2)

Je veux prendre une capture d'écran de cette vue uniquement et non de tout mon écran. Et faites la capture d'écran de la taille:

 (CGSizeMake(2480,3508 )

Voici mon code:

UIGraphicsBeginImageContextWithOptions(CGSizeMake(2480,3508 ), false, 0);
self.view.drawViewHierarchyInRect(CGRectMake(-self.view.frame.width/25, -self.view.frame.height/25,2480,3508), afterScreenUpdates: true)
var image:UIImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext()

La capture d'écran est de la taille requise, mais elle prend la capture d'écran de la vue entière au lieu de simplement "overView".

25
Sameer Hussain

Pour dessiner une vue, utilisez simplement ceci:

    // Begin context
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, UIScreen.mainScreen().scale)

    // Draw view in that context
    drawViewHierarchyInRect(view.bounds, afterScreenUpdates: true)

    // And finally, get image
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

Si vous souhaitez l'utiliser plusieurs fois, probablement l'extension fera l'affaire:

// Swift4

extension UIView {

    func takeScreenshot() -> UIImage {

        // Begin context
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)

        // Draw view in that context
        drawHierarchy(in: self.bounds, afterScreenUpdates: true)

        // And finally, get image
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        if (image != nil)
        {
            return image!
        }
        return UIImage()
    }
}

// Old Swift

extension UIView {

    func takeScreenshot() -> UIImage {

        // Begin context
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.mainScreen().scale)

        // Draw view in that context
        drawViewHierarchyInRect(self.bounds, afterScreenUpdates: true)

        // And finally, get image
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }
}

Pour expliquer ce que font ces paramètres:

UIGraphicsBeginImageContextWithOptions () crée un contexte de rendu temporaire dans lequel l'original est dessiné. Le premier argument, taille, est la taille cible de l'image mise à l'échelle. Le deuxième argument, isOpaque est utilisé pour déterminer si un canal alpha est rendu. La définition de ce paramètre sur false pour les images sans transparence (c'est-à-dire un canal alpha) peut entraîner une image avec une teinte rose. La troisième échelle d'arguments est le facteur d'échelle d'affichage. Lorsqu'il est réglé sur 0,0, le facteur d'échelle de l'écran principal est utilisé, ce qui pour les écrans Retina est 2,0 ou supérieur (3,0 sur l'iPhone 6 Plus).

En savoir plus ici http://nshipster.com/image-resizing/

Quant à l'appel de tirage, Apple Docs l'explique en détail ici et ici

46
Jiri Trecak

Swift 4 et iOS 10+

extension UIView {

  func screenshot() -> UIImage {
    return UIGraphicsImageRenderer(size: bounds.size).image { _ in
      drawHierarchy(in: CGRect(Origin: .zero, size: bounds.size), afterScreenUpdates: true)
    }
  }

}
15
Alessandro

Une alternative pour réponse d'Alessandro , un peu plus bref et Swift style:

extension UIView {

    var snapshot: UIImage {
        return UIGraphicsImageRenderer(size: bounds.size).image { _ in
            drawHierarchy(in: bounds, afterScreenUpdates: true)
        }
    }

}
4
Ángel Téllez

Pour prendre un écran court, utilisez cette solution. Écoutez, je peux faire Comment prendre un écran court UIView avec UIImage.

let img = self.captureScreen() // CaptureScreen Is A Function
        let someNSDate = NSDate()
        let myTimeStamp = someNSDate.timeIntervalSince1970
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]

if let data = UIImageJPEGRepresentation(img, 0.8)
{
    let filename = documentsDirectory.appendingPathComponent("Img_\(myTimeStamp).jpeg")
    SavedImage_Ary.insert("Img_\(myTimeStamp).jpeg", at: 0) // SavedImage Is A NSMutableArray Where You Can Store your Image
    //print(SavedImage_Ary)
    try? data.write(to: filename)
    UserDefaults.standard.setValue(SavedImage_Ary, forKey: "Saved_Image")
    Save_Img = true
    //            self.dismiss(animated: true, completion: nil)
    Select_Flag = "textdata"
    let vc = self.storyboard?.instantiateViewController(withIdentifier: "photovc") as! UINavigationController
    self.present(vc, animated: true, completion: nil)
}


// MARK : Function

func captureScreen() -> UIImage
{

    UIGraphicsBeginImageContextWithOptions(Capture_View.frame.size, false, 0);
    Capture_View.drawHierarchy(in: Capture_View.bounds, afterScreenUpdates: true)
    let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return image
}
2
Dhaval Gevariya

Swift 4.x et iOS 10+ avec solution de secours:

extension UIView {
    func screenshot() -> UIImage {
        if #available(iOS 10.0, *) {
            return UIGraphicsImageRenderer(size: bounds.size).image { _ in
                drawHierarchy(in: CGRect(Origin: .zero, size: bounds.size), afterScreenUpdates: true)
            }
        } else {
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
            drawHierarchy(in: self.bounds, afterScreenUpdates: true)
            let image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
            UIGraphicsEndImageContext()
            return image
        }
    }
}
0
Hemang
func screenShotMethod()->UIImage
    {
        let layer = self.view.layer
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

        layer.render(in: UIGraphicsGetCurrentContext()!)
        let screenshot = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return screenshot!
    }
0
Sidharth Khanna