今天做項(xiàng)目的時(shí)候需要自定義裁切來(lái)自相機(jī)圖庫(kù)選擇的圖片殷蛇,找了一圈資料發(fā)現(xiàn)相關(guān)的信息甚少登馒。爬了好幾個(gè)小時(shí)的坑痊硕,分享給大家~
開始之前忍不住吐槽一手蘋果场钉,既然系統(tǒng)提供了選取圖片后的裁切功能,讓開發(fā)者傳個(gè)CGRect敢辩,CGSize進(jìn)去不應(yīng)該理所當(dāng)然嗎蔽莱?搞得我一開始瘋狂的查水果的 API Reference,最后得出一個(gè)無(wú)奈的結(jié)論戚长。盗冷。。寬高定死同廉,你愛(ài)用不用:)仪糖。。迫肖。難道蘋果認(rèn)為用戶對(duì)圖片的需求大小只有那么一種嗎锅劝?。蟆湖。故爵。
其實(shí)自定義裁剪器主要就是核心繪圖
1.畫個(gè)遮罩出來(lái)
UIGraphicsBeginImageContextWithOptions(UIScreen.main.bounds.size, false, 0)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5).cgColor)
context?.fill(UIScreen.main.bounds)
context?.addRect(CGRect(x: 0, y: (HEIGHT - selectHeight)/2, width: WIDTH , height: selectHeight))
context?.setBlendMode(.clear)
context?.fillPath()
let img = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let selectarea = UIImageView(image: img)
selectarea.frame.origin = CGPoint(x: 0, y: 0)
view.addSubview(selectarea)
2.裁剪圖片(核心部分到這里就結(jié)束了)
let rect = UIScreen.main.bounds
// 記錄屏幕縮放比
let scal = UIScreen.main.scale
// 上下文
UIGraphicsBeginImageContextWithOptions(rect.size, true, 0)
let context = UIGraphicsGetCurrentContext()
UIApplication.shared.keyWindow?.layer.render(in: context!)
// 截全屏,再截圖
guard let img = UIGraphicsGetImageFromCurrentImageContext()?.cgImage,
let result = img.cropping(to: CGRect(x: 0, y: (HEIGHT - selectHeight)/2 * scal, width: self.WIDTH * scal, height: selectHeight * scal)) else{
return nil
}
// 關(guān)閉上下文
UIGraphicsEndImageContext()
}
3.定一個(gè)協(xié)議來(lái)傳值
protocol SwiftyPhotoClipperDelegate {
func didFinishClippingPhoto(image:UIImage)
}
4.忘了一步隅津,關(guān)于圖片的縮放稠集,一個(gè) scrollview ,當(dāng)他的 maximumZoomScale 和 minimumZoomScale 不同并且實(shí)現(xiàn) viewForZooming 返回縮放視圖即可饥瓷。
代碼很簡(jiǎn)單,沒(méi)什么好貼的痹籍,就貼一個(gè)定位代碼吧
func scrollViewDidZoom(_ scrollView: UIScrollView) {
//當(dāng)捏或移動(dòng)時(shí)呢铆,需要對(duì)center重新定義以達(dá)到正確顯示位置
var centerX = scrollView.center.x
var centerY = scrollView.center.y
centerX = scrollView.contentSize.width > scrollView.frame.size.width ? scrollView.contentSize.width / 2 : centerX
centerY = scrollView.contentSize.height > scrollView.frame.size.height ?scrollView.contentSize.height / 2 : centerY
self.imgView?.center = CGPoint(x: centerX, y: centerY)
}
5.然后就是使用了,在 didFinishPickingMediaWithInfo 中 跳轉(zhuǎn)到我們的自定義裁剪器即可
//選擇圖片成功后代理
func imagePickerController(_ picker: UIImagePickerController,didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
picker.dismiss(animated: false, completion: {
let clipper = SwiftyPhotoClipper()
clipper.delegate = self
clipper.img = image
self.present(clipper, animated: true, completion: nil)
})
} else{
print("Something went wrong")
}
}
完整demo:https://github.com/KFCFans/SwiftyPhotoClipper
求 Star 啦~么么噠~