Swift &引用;在展开可选值“时意外发现nil”;内置captureOutput函数
我有一个函数可以旋转UIImages上的色调,这些图像来自同一类中的其他函数,但在captureOutput函数(与AVCaptureVideoDataOutput一起使用)中,同一图像对象会使我的应用程序崩溃,并显示“在展开可选值时意外发现零”。我对它的调用方式似乎没有什么不同,所以它可能与captureOutput函数及其允许的功能有关 在viewController类声明之外:Swift &引用;在展开可选值“时意外发现nil”;内置captureOutput函数,swift,optional,capture-output,Swift,Optional,Capture Output,我有一个函数可以旋转UIImages上的色调,这些图像来自同一类中的其他函数,但在captureOutput函数(与AVCaptureVideoDataOutput一起使用)中,同一图像对象会使我的应用程序崩溃,并显示“在展开可选值时意外发现零”。我对它的调用方式似乎没有什么不同,所以它可能与captureOutput函数及其允许的功能有关 在viewController类声明之外: var image:UIImage? = nil var imageSource:UIImage? = nil
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)
}
UIImage
的cgImage
属性的文档说明如下:
如果UIImage对象是使用CIImage对象初始化的,则该属性的值为NULL
由于此值可以是nil
,因此不应使用强制展开(!
)操作符,否则可能会发生崩溃,正如您所看到的那样。相反,我们需要测试该值可能为nil
的条件
幸运的是,使cgImage
变为nil
的条件是它显然是使用CIImage
初始化的。既然你想要的是CIImage
,那么正确的方法就是:
UIImage
的ciImage
属性,如果得到非nil值,则使用该属性李>
ciImage
为nil
,则返回调用cgImage
并在其为非nil
时从中生成ciImage
cgImage
恰好也为零,则发生了一些奇怪的事情;在这种情况下,您可以抛出错误或以其他方式优雅地退出UIImage
的cgImage
属性的文档说明如下:
如果UIImage对象是使用CIImage对象初始化的,则该属性的值为NULL
由于此值可以是nil
,因此不应使用强制展开(!
)操作符,否则可能会发生崩溃,正如您所看到的那样。相反,我们需要测试该值可能为nil
的条件
幸运的是,使cgImage
变为nil
的条件是它显然是使用CIImage
初始化的。既然你想要的是CIImage
,那么正确的方法就是:
UIImage
的ciImage
属性,如果得到非nil值,则使用该属性李>
ciImage
为nil
,则返回调用cgImage
并在其为非nil
时从中生成ciImage
cgImage
恰好也为零,则发生了一些奇怪的事情;在这种情况下,您可以抛出错误或以其他方式优雅地退出崩溃时哪个值为零?这是你的第一条线索。如果可能的话,你应该避免使用强制展开(
!
)。始终使用if let
或guard let
安全地打开包装。我以为它会是“图像”,但如果我去掉rotateHue的函数调用,它不会崩溃,并在应用程序上显示相机输出。在rotateHue()中分配sourceCore时发生。崩溃时哪个值为零?这是你的第一条线索。如果可能的话,你应该避免使用强制展开(!
)。始终使用if let
或guard let
安全地打开包装。我以为它会是“图像”,但如果我去掉rotateHue的函数调用,它不会崩溃,并在应用程序上显示相机输出。在rotateHue()中分配sourceCore时发生。UIImage的ciImage似乎是非nil的,它调用函数并以相同的方式崩溃:if(image?.ciImage!=nil)image=rotateHue(with:image!,rotatedByHue:hueDeg)@这说明只要image
为nil,就会崩溃。不要用力展开。如果let或保护let
或?
则使用。@同样,也不要测试image?.ciImage!=nil
,如果让ciImage=image?.ciImage
执行类似于的操作,然后使用生成的ciImage
。我建议更改rotateHue
的签名以获取CIImage
而不是UIImage
,然后将从if let
中获得的值传递给它。UIImage的CIImage似乎不是nil,它调用函数并以相同的方式崩溃:if(image?.CIImage!=nil)image=rotateHue(使用:image!,按色调:hueDeg旋转)@模糊解释:当image
为零时,一个将崩溃。不要使用强制展开。如果let
或保护let
或则使用?
。@模糊解释也不是测试image?.ciImage!=nil
,你应该做类似的事情,如果let ciImage=image?.ciImage
,然后使用结果使用CIImage
。我建议将rotateHue
的签名更改为使用CIImage
而不是UIImage
,然后将从中获得的值传递给它(如果让)。