Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios CGImageCreateWithImageInRect()返回nil_Ios_Swift_Optional_Cgimage - Fatal编程技术网

Ios CGImageCreateWithImageInRect()返回nil

Ios CGImageCreateWithImageInRect()返回nil,ios,swift,optional,cgimage,Ios,Swift,Optional,Cgimage,我试图将图像裁剪成正方形,但一旦我实际尝试使用CGImageCreateWithImageInRect()进行裁剪,这一行就会崩溃。我设置了断点,并确保传递到此函数的参数不是nil 我对编程和Swift相当陌生,但我四处搜索,没有找到任何解决问题的方法 失败原因: 致命错误:在展开可选值时意外发现nil 您的代码使用了大量的强制展开s。我建议避免这种情况——编译器试图帮助您编写不会崩溃的代码。与?一起使用可选链接,如果let/保护let,则使用 隐藏了一个问题,其中CGImageCreateWi

我试图将图像裁剪成正方形,但一旦我实际尝试使用CGImageCreateWithImageInRect()进行裁剪,这一行就会崩溃。我设置了断点,并确保传递到此函数的参数不是nil

我对编程和Swift相当陌生,但我四处搜索,没有找到任何解决问题的方法

失败原因:

致命错误:在展开可选值时意外发现nil


您的代码使用了大量的强制展开
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
自动将其居中。哦,多么方便!太棒了。非常感谢你。