Ios CGImageCreateWithImageInRect()返回nil
我试图将图像裁剪成正方形,但一旦我实际尝试使用CGImageCreateWithImageInRect()进行裁剪,这一行就会崩溃。我设置了断点,并确保传递到此函数的参数不是nil 我对编程和Swift相当陌生,但我四处搜索,没有找到任何解决问题的方法 失败原因: 致命错误:在展开可选值时意外发现nilIos CGImageCreateWithImageInRect()返回nil,ios,swift,optional,cgimage,Ios,Swift,Optional,Cgimage,我试图将图像裁剪成正方形,但一旦我实际尝试使用CGImageCreateWithImageInRect()进行裁剪,这一行就会崩溃。我设置了断点,并确保传递到此函数的参数不是nil 我对编程和Swift相当陌生,但我四处搜索,没有找到任何解决问题的方法 失败原因: 致命错误:在展开可选值时意外发现nil 您的代码使用了大量的强制展开s。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。与?一起使用可选链接,如果let/保护let,则使用 隐藏了一个问题,其中CGImageCreateWi
您的代码使用了大量的强制展开
代码>s。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。与?
一起使用可选链接,如果let
/保护let
,则使用
该行上的代码>隐藏了一个问题,其中CGImageCreateWithImageInRect可能返回nil。说明当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()
您的代码使用了大量的强制展开代码>s。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。与?
一起使用可选链接,如果let
/保护let
,则使用
该行上的代码>隐藏了一个问题,其中CGImageCreateWithImageInRect可能返回nil。说明当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()
我敢打赌,rect
是不对的。我不确定你在做什么,但是你将它设置为高度加上宽度和高度之差的一半(这一点对我来说没有意义),然后尝试得到一个矩形,它从posY
开始,然后又是图像的高度。因此,posY
加上这个奇怪的高度可能会产生一个CGRect
,它不在原始图像的大小之内。我打赌CGImageCreateWithImageInRect
失败,因为它无法使用传递给它的rect
。此外,但不相关的是,您还将数据转换为UIImage
,获取其CGImage
,从中创建另一个uimage
,然后再次获取CGImage
。这一切似乎都不必要地错综复杂。我不确定你想用contextImage
做什么,但我想退出,在你调用CGImageCreateWithImageInRect
时使用你的image.CGImage
。我想用posY
做的是从图像中心裁剪一个正方形,而不是从顶部。此外,尽管我限制仅使用肖像图像,但打印出contextSize
会使高度和宽度颠倒。(由于某种原因,高度实际上小于宽度)我敢打赌rect
是不对的。我不确定你在做什么,但是你将它设置为高度加上宽度和高度之差的一半(这一点对我来说没有意义),然后尝试得到一个矩形,它从posY
开始,然后又是图像的高度。因此,posY
加上这个奇怪的高度可能会产生一个CGRect
,它不在原始图像的大小之内。我打赌CGImageCreateWithImageInRect
失败,因为它无法使用传递给它的rect
。此外,但不相关的是,您还将数据转换为UIImage
,获取其CGImage
,从中创建另一个uimage
,然后再次获取CGImage
。这一切似乎都不必要地错综复杂。我不确定你想用contextImage
做什么,但我想退出,在你调用CGImageCreateWithImageInRect
时使用你的image.CGImage
。我想用posY
做的是从图像中心裁剪一个正方形,而不是从顶部。此外,尽管我限制仅使用肖像图像,但打印出contextSize
会使高度和宽度颠倒。(由于某种原因,高度实际上小于宽度)谢谢@jtbandes。我没有想到使用avmakerect和aspectratioinsidect
。我不明白的是,图像是如何在中间被裁剪的?我不明白这段代码是如何正确实现的。AVMakeRectWithAspectRatioInsideRect
自动将其居中。哦,多么方便!太棒了。非常感谢。谢谢@jtbandes。我没有想到使用avmakerect和aspectratioinsidect
。我不明白的是,图像是如何在中间被裁剪的?我不明白这段代码是如何正确实现的。AVMakeRectWithAspectRatioInsideRect
自动将其居中。哦,多么方便!太棒了。非常感谢你。