CGImageCreateWithImageInRect() 返回零
CGImageCreateWithImageInRect() returning nil
我正在尝试将图像裁剪成正方形,但一旦我实际尝试使用 CGImageCreateWithImageInRect() 进行裁剪,此行就会崩溃。我设置了断点并确保传递给这个函数的参数不为零。
我对编程还很陌生,Swift,但我四处搜索并没有找到解决我的问题的方法。
失败原因:
fatal error: unexpectedly found nil while unwrapping an Optional value
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!
}
您的代码使用了很多 !
的强制展开。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。使用带有 ?
和 if let
/ guard let
的可选链接。
该特定行上的 !
隐藏了 CGImageCreateWithImageInRect 可能 return 为零的问题。 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()
我正在尝试将图像裁剪成正方形,但一旦我实际尝试使用 CGImageCreateWithImageInRect() 进行裁剪,此行就会崩溃。我设置了断点并确保传递给这个函数的参数不为零。
我对编程还很陌生,Swift,但我四处搜索并没有找到解决我的问题的方法。
失败原因:
fatal error: unexpectedly found nil while unwrapping an Optional value
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!
}
您的代码使用了很多 !
的强制展开。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。使用带有 ?
和 if let
/ guard let
的可选链接。
该特定行上的 !
隐藏了 CGImageCreateWithImageInRect 可能 return 为零的问题。 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()