我正在做基于注意力的显着性,应该将图像传递给请求。当contentMode为ScaleAspectFill时,请求的结果不正确,因为我使用的是完整图像(在屏幕部分不可见)
我正在尝试裁剪 UIImage,但此方法无法正确裁剪
let newImage = cropImage(imageToCrop: imageView.image, toRect: imageView.frame)
func cropImage(imageToCrop: UIImage?, toRect rect: CGRect) -> UIImage? {
guard let imageRef = imageToCrop?.cgImage?.cropping(to: rect) else {
return nil
}
let cropped: UIImage = UIImage(cgImage: imageRef)
return cropped
}
如何仅针对图像的可见部分(当更改 contentMode 时会发生变化)发出显着性请求?
如果我正确理解你的目标...
假设我们有这个
640 x 360
图像:
我们使用
240 x 240
...将其显示在
.scaleAspectFill
图像视图中
它看起来像这样(红色轮廓是图像视图框架):
并且,与
.clipsToBounds = true
:
我们想要生成这个新
360 x 360
图像(也就是说,我们想要保持原始图像分辨率......我们不想最终得到一个240 x 240
图像):
要裁剪图像的可见部分,我们需要计算缩放后的矩形,包括偏移量:
func cropImage(imageToCrop: UIImage?, toRect rect: CGRect) -> UIImage? {
guard let imageRef = imageToCrop?.cgImage?.cropping(to: rect) else {
return nil
}
let cropped: UIImage = UIImage(cgImage: imageRef)
return cropped
}
func myCrop(imgView: UIImageView) -> UIImage? {
// get the image from the imageView
guard let img = imgView.image else { return nil }
// image view rect
let vr: CGRect = imgView.bounds
// image size -- we need to account for scale
let imgSZ: CGSize = CGSize(width: img.size.width * img.scale, height: img.size.height * img.scale)
let viewRatio: CGFloat = vr.width / vr.height
let imgRatio: CGFloat = imgSZ.width / imgSZ.height
var newRect: CGRect = .zero
// calculate the rect that needs to be clipped from the full image
if viewRatio > imgRatio {
// image has a wider aspect ratio than the image view
// so top and bottom will be clipped
let f: CGFloat = imgSZ.width / vr.width
let h: CGFloat = vr.height * f
newRect.origin.y = (imgSZ.height - h) * 0.5
newRect.size.width = imgSZ.width
newRect.size.height = h
} else {
// image has a narrower aspect ratio than the image view
// so left and right will be clipped
let f: CGFloat = imgSZ.height / vr.height
let w: CGFloat = vr.width * f
newRect.origin.x = (imgSZ.width - w) * 0.5
newRect.size.width = w
newRect.size.height = imgSZ.height
}
return cropImage(imageToCrop: img, toRect: newRect)
}
并这样称呼它:
if let croppedImage = myCrop(imgView: theImageView) {
// do something with the new image
}