使用屏幕纵横比裁剪 UIImage 的一部分
Cropping part of UIImage with the screen aspect ratio
我已经为此苦苦挣扎了一段时间。当你 select 你的墙纸时,我想制作类似于 iOS 本身包含的图像裁剪器。基本上我想要用户 selects 从具有缩放和屏幕纵横比的图像中裁剪的区域(以便用户稍后可以将图像用作墙纸)。像这样:
https://gfycat.com/TornMaleAlligatorsnappingturtle
我已经成功创建了与 UIScrollView 和 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)
}
}.
我可以毫无问题地缩放和平移图像。问题是我不知道如何创建代表显示给用户的区域的 CGRect 矩形,这也是我想从原始图像中裁剪的区域。非常感谢任何能让我摆脱痛苦的想法!
snapshotImageFromMyView 是输出图像
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()
}
我已经为此苦苦挣扎了一段时间。当你 select 你的墙纸时,我想制作类似于 iOS 本身包含的图像裁剪器。基本上我想要用户 selects 从具有缩放和屏幕纵横比的图像中裁剪的区域(以便用户稍后可以将图像用作墙纸)。像这样:
https://gfycat.com/TornMaleAlligatorsnappingturtle
我已经成功创建了与 UIScrollView 和 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)
}
}.
我可以毫无问题地缩放和平移图像。问题是我不知道如何创建代表显示给用户的区域的 CGRect 矩形,这也是我想从原始图像中裁剪的区域。非常感谢任何能让我摆脱痛苦的想法!
snapshotImageFromMyView 是输出图像
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()
}