【发布时间】:2017-09-28 23:08:00
【问题描述】:
我正在尝试使用覆盖层UIView 裁剪图像视图的子图像,该覆盖层可以放置在UIImageView 的任何位置。当 UIImageView 内容模式为“Aspect Fit”时,我从类似的帖子中借用了一个解决方案。建议的解决方案是:
func computeCropRect(for sourceFrame : CGRect) -> CGRect {
let widthScale = bounds.size.width / image!.size.width
let heightScale = bounds.size.height / image!.size.height
var x : CGFloat = 0
var y : CGFloat = 0
var width : CGFloat = 0
var height : CGFloat = 0
var offSet : CGFloat = 0
if widthScale < heightScale {
offSet = (bounds.size.height - (image!.size.height * widthScale))/2
x = sourceFrame.origin.x / widthScale
y = (sourceFrame.origin.y - offSet) / widthScale
width = sourceFrame.size.width / widthScale
height = sourceFrame.size.height / widthScale
} else {
offSet = (bounds.size.width - (image!.size.width * heightScale))/2
x = (sourceFrame.origin.x - offSet) / heightScale
y = sourceFrame.origin.y / heightScale
width = sourceFrame.size.width / heightScale
height = sourceFrame.size.height / heightScale
}
return CGRect(x: x, y: y, width: width, height: height)
}
问题在于,当图像视图为纵横填充时使用此解决方案会导致裁剪的片段与覆盖UIView 的位置不完全对齐。我不太确定如何调整此代码以适应 Aspect Fill 或重新定位我的叠加层UIView,以便它与我要裁剪的片段 1:1 对齐。
UPDATE 使用下面的 Matt 的回答解决了
class ViewController: UIViewController {
@IBOutlet weak var catImageView: UIImageView!
private var cropView : CropView!
override func viewDidLoad() {
super.viewDidLoad()
cropView = CropView(frame: CGRect(x: 0, y: 0, width: 45, height: 45))
catImageView.image = UIImage(named: "cat")
catImageView.clipsToBounds = true
catImageView.layer.borderColor = UIColor.purple.cgColor
catImageView.layer.borderWidth = 2.0
catImageView.backgroundColor = UIColor.yellow
catImageView.addSubview(cropView)
let imageSize = catImageView.image!.size
let imageViewSize = catImageView.bounds.size
var scale : CGFloat = imageViewSize.width / imageSize.width
if imageSize.height * scale < imageViewSize.height {
scale = imageViewSize.height / imageSize.height
}
let croppedImageSize = CGSize(width: imageViewSize.width/scale, height: imageViewSize.height/scale)
let croppedImrect =
CGRect(origin: CGPoint(x: (imageSize.width-croppedImageSize.width)/2.0,
y: (imageSize.height-croppedImageSize.height)/2.0),
size: croppedImageSize)
let renderer = UIGraphicsImageRenderer(size:croppedImageSize)
let _ = renderer.image { _ in
catImageView.image!.draw(at: CGPoint(x:-croppedImrect.origin.x, y:-croppedImrect.origin.y))
}
}
@IBAction func performCrop(_ sender: Any) {
let cropFrame = catImageView.computeCropRect(for: cropView.frame)
if let imageRef = catImageView.image?.cgImage?.cropping(to: cropFrame) {
catImageView.image = UIImage(cgImage: imageRef)
}
}
@IBAction func resetCrop(_ sender: Any) {
catImageView.image = UIImage(named: "cat")
}
}
【问题讨论】:
-
但是你的新素材显示了一个屏幕截图,其中原始图像不受
aspectFill或aspectFit影响;正在显示整个图像!我认为您的图像视图的配置方式与您想象的不同。 -
我仔细检查了两个图像视图都设置为
aspectFill。可能是因为我直接将aspectCroppedImage分配给destinationImageView? -
为了清晰起见,我将快速更新我的实现和屏幕截图。
-
那么你在完全错误的时间创建
aspectCroppedImage。 -
什么时候实际调用计算它的代码?
标签: ios objective-c iphone uiview uiimageview