我试图将图像裁剪成正方形,但是一旦我尝试使用CGImageCreateWithImageInRect()进行裁剪,此线就会崩溃。我设置断点并确保传递给此函数的参数不是nil。
我对编程和Swift相当陌生,但已经四处寻找并找不到解决问题的方法。
失败原因:
致命错误:在解包可选值时意外发现nil
func cropImageToSquare(imageData: NSData) -> NSData {
let image = UIImage(data: imageData)
let contextImage : UIImage = UIImage(CGImage: image!.CGImage!)
let contextSize: CGSize = contextImage.size
let imageDimension: CGFloat = contextSize.height
let posY : CGFloat = (contextSize.height + (contextSize.width - contextSize.height)/2)
let rect: CGRect = CGRectMake(0, posY, imageDimension, imageDimension)
// error on line below: fatal error: unexpectedly found nil while unwrapping an Optional value
let imageRef: CGImageRef = CGImageCreateWithImageInRect(contextImage.CGImage, rect)!
let croppedImage : UIImage = UIImage(CGImage: imageRef, scale: 1.0, orientation: image!.imageOrientation)
let croppedImageData = UIImageJPEGRepresentation(croppedImage, 1.0)
return croppedImageData!
}
答案 0 :(得分:0)
您的代码使用了很多强制解包!
s。我建议避免这种情况 - 编译器正在尝试帮助您编写不会崩溃的代码。使用与?
和if let
/ guard let
的可选链接。
该特定行上的!
隐藏了CGImageCreateWithImageInRect可能返回nil的问题。 The documentation解释说,当rect
未在图像边界内正确时,会发生这种情况。您的代码适用于纵向图像,但不适用于横向图像。
此外,AVFoundation提供了一个方便的功能,它可以自动找到你要使用的正确矩形,称为AVMakeRectWithAspectRatioInsideRect
。无需手动进行计算: - )
以下是我的建议:
import AVFoundation
extension UIImage
{
func croppedToSquare() -> UIImage
{
guard let cgImage = self.CGImage else { return self }
// Note: self.size depends on self.imageOrientation, so we use CGImageGetWidth/Height here.
let boundingRect = CGRect(
x: 0, y: 0,
width: CGImageGetWidth(cgImage),
height: CGImageGetHeight(cgImage))
// Crop to square (1:1 aspect ratio) and round the resulting rectangle to integer coordinates.
var cropRect = AVMakeRectWithAspectRatioInsideRect(CGSize(width: 1, height: 1), boundingRect)
cropRect.origin.x = ceil(cropRect.origin.x)
cropRect.origin.y = ceil(cropRect.origin.y)
cropRect.size.width = floor(cropRect.size.width)
cropRect.size.height = floor(cropRect.size.height)
guard let croppedImage = CGImageCreateWithImageInRect(cgImage, cropRect) else {
assertionFailure("cropRect \(cropRect) was not inside \(boundingRect)")
return self
}
return UIImage(CGImage: croppedImage, scale: self.scale, orientation: self.imageOrientation)
}
}
// then:
let croppedImage = myUIImage.croppedToSquare()