0

我有一个函数来旋转 UIImages 上的色调,该函数与同一类中的其他函数一起工作,但在 captureOutput 函数(与 AVCaptureVideoDataOutput 一起使用)中,相同的图像对象使我的应用程序崩溃,并显示“在展开可选值时意外发现 nil” . 我调用它的方式看起来没有什么不同,所以它可能与 captureOutput 函数及其允许的功能有关?

在 viewController 类声明之外:

var image:UIImage? = nil
var imageSource:UIImage? = nil
var imageView:UIImageView? = nil;
var hueDeg:CGFloat = 0.00

功能:

func rotateHue(with source: UIImage, rotatedByHue deltaHueRadians: CGFloat) -> UIImage {
    // Create a Core Image version of the image.
    let sourceCore = CIImage(cgImage: (source.cgImage)!) // crashes here
    // Apply a CIHueAdjust filter
    let hueAdjust = CIFilter(name: "CIHueAdjust")
    hueAdjust?.setDefaults()
    hueAdjust?.setValue(sourceCore, forKey: "inputImage")
    hueAdjust?.setValue(deltaHueRadians, forKey: "inputAngle")
    let resultCore = hueAdjust?.value(forKey: "outputImage") as? CIImage
    // Convert the filter output back into a UIImage.
    let context = CIContext(options: nil)
    let resultRef = context.createCGImage(resultCore!, from: (resultCore?.extent)!)
    let result = UIImage(cgImage: resultRef!)
    //CGImageRelease(resultRef)
    return result
}

func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection){
    let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
    let cameraImage = CIImage(cvPixelBuffer: pixelBuffer!)

    image = UIImage(ciImage: cameraImage)

    image = rotateHue(with:image!, rotatedByHue:hueDeg) 

    DispatchQueue.main.async(){

        imageView!.image = image
    }

}

这是我调用 rotateHue 的另一个函数,它不会崩溃。这是一个由计时器调用的函数:

@objc func cycleHue(){
    hueDeg += 0.2;
    image = imageSource
    image = rotateHue(with:image!, rotatedByHue:hueDeg)
    imageView!.image = UIImage(cgImage: (image?.cgImage)!, scale: 1.0, orientation: UIImageOrientation.right)
}
4

1 回答 1

4

UIImage'cgImage属性的文档是这样说的:

如果 UIImage 对象是使用 CIImage 对象初始化的,则该属性的值为 NULL。

由于该值可以是nil,因此您不应该使用 force-unwrap ( !) 运算符,否则您可能会遇到崩溃,如您所见。相反,我们需要测试该值可能为 的条件nil

幸运的是,成为cgImagebe的条件nil是它显然是使用CIImage. 既然看起来 aCIImage是你想要,那么正确的方法是:

  1. callUIImageciImage属性,如果你得到一个非零值,使用它。
  2. 如果ciImagenil,那么如果它不是 ,则返回调用并从中cgImage制作 a 。CIImagenil
  3. 如果cgImage 恰好是 nil,那么奇怪的事情发生了;在这种情况下,您可以抛出错误或以其他方式优雅地退出。
于 2017-10-27T20:58:13.707 回答