2017-08-17 2 views
0

Cela fait longtemps que je me bats avec ça. Je voudrais faire un recadrage d'image similaire à celui inclus dans iOS lui-même lorsque vous sélectionnez votre fond d'écran. Fondamentalement, je veux la zone que l'utilisateur sélectionne recadrée de l'image avec le zoom et le ratio d'aspect de l'écran (de sorte que l'utilisateur peut utiliser l'image comme fond d'écran plus tard). Comme ceci:Recadrage d'UIImage avec le format de l'écran

https://gfycat.com/TornMaleAlligatorsnappingturtle

J'ai réussi à créer l'interface avec UIScrollView et UIImageView:

import UIKit 

class ViewController: UIViewController, UIScrollViewDelegate { 

var scrollView: UIScrollView! 
var imageView: UIImageView! 

var croppedImage: UIImage? 

@IBOutlet weak var cropButton: UIButton! { 
    didSet{ 
     cropButton.backgroundColor = UIColor.gray 
    } 
} 


override func viewDidLoad() { 

    super.viewDidLoad() 

    let image = UIImage(named: "mountains")! 

    imageView = UIImageView(image: image) 
    imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size:image.size) 
    imageView.contentMode = .scaleAspectFill 

    scrollView = UIScrollView(frame: view.bounds) 
    scrollView.backgroundColor = UIColor.black 
    scrollView.contentSize = imageView.bounds.size 

    scrollView.delegate = self 

    setZoomScale() 
    //centerScrollViewContents() 

    scrollView.addSubview(imageView) 
    view.addSubview(scrollView) 
    view.bringSubview(toFront: cropButton) 

} 

func viewForZooming(in scrollView: UIScrollView) -> UIView? { 
    return imageView 
} 

@IBAction func crop(_ sender: UIButton) { 

    let rect = CGRect(x: ?, y: ?, width: ?, height: ?) 
    let croppedCGImage = imageView.image?.cgImage?.cropping(to: rect) 
    self.croppedImage = UIImage(cgImage: croppedCGImage!) 
} 

func setZoomScale() { 
    let imageViewSize = imageView.bounds.size 
    let scrollViewSize = scrollView.bounds.size 
    //let widthScale = scrollViewSize.width/imageViewSize.width 
    let heightScale = scrollViewSize.height/imageViewSize.height 

    scrollView.minimumZoomScale = heightScale //min(widthScale, heightScale) 
    scrollView.maximumZoomScale = 3 
    scrollView.zoomScale = heightScale 

    print(heightScale) 
} 
}. 

Je peux zoomer et pan autour de l'image sans problème. Le problème est que je ne sais pas comment créer le rectangle CGRect qui représente la zone qui est affichée à l'utilisateur, qui est également la zone que je veux recadrer à partir de l'image originale. Toutes les idées qui me mettront hors de ma misère sont grandement appréciées!

Répondre

3

snapshotImageFromMyView est l'image de sortie

self.btn.isHidden = true 

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { 
     UIGraphicsBeginImageContextWithOptions(self.YourView.bounds.size, self.YourView.isOpaque, 0.0) 
     self.YourView.drawHierarchy(in: self.YourView.bounds, afterScreenUpdates: false) 
    let snapshotImageFromMyView = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

} 
+0

Cela fonctionne bien, mais j'ai boutons à l'écran qui se aswell snapshotted, même si je les cache via la propriété isHidden. – MHCsk

+0

cacher les choses que vous ne voulez pas faire partie de la capture d'écran @MHCsk –

+0

J'appelle self.cropButton.isHidden = true juste avant le code, mais le bouton est toujours visible sur l'instantané. – MHCsk