“fatal error: unexpectedly found nil while unwrapp

2019-07-16 03:48发布

问题:

I'm working in Swift iOS8 and trying to convert UIImage to vImage_Buffer to perform manipulations using Accelerate.framework. I'm trying to use vImageBuffer_initWithCGImage for conversion, here is the code that I tried:

func initvImageBufferwithUIImage (image:UIImage)-> vImage_Buffer{

    var CGImg:CGImageRef = sunset.CGImage
    var inProvider:CGDataProviderRef = CGImageGetDataProvider(CGImg)
    var inBitmapData:CFDataRef = CGDataProviderCopyData(inProvider)
    var buffer:vImage_Buffer!

    var format:vImage_CGImageFormat = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 32, colorSpace: nil, bitmapInfo: CGBitmapInfo.ByteOrderDefault, version: 0, decode: nil, renderingIntent: kCGRenderingIntentDefault)

    vImageBuffer_InitWithCGImage(&buffer!, &format, nil , sunset.CGImage, 0)

    return buffer

There is no compilation error and wen I try to run it I get "fatal error: unexpectedly found nil while unwrapping an Optional value" on the line of vImageBuffer_InitWithCGImage. I'm not sure why it's happening since both buffer and 3rd parameter which is backgroundColor are both unsafe and according to documentation are supposed to accept NULL which is nil in swift for UnsafeMutablePointer (correct me if I'm wrong).

EDIT: ok I at least understood why now its happening. Because I send unwrapped &buffer!. But I CANT send &buffer since it says that "vImage_buffer! is not identical to vImage_buffer".

I tried all kind of combinations with declaring buffer as vImage_buffer? but I cant manage to make it work. I basically just need to allocate the buffer parameter to pass it into init function but I dont know how to ... . Please help

回答1:

I have no idea on what vImage is. But from the apple doc, the vImage_Buffer is a struct, which should has a body before you parse it to vImageBuffer_InitWithCGImage, and that function will fill in fields for that struct. The real problem of your code is.

var buffer:vImage_Buffer!

Above one create an optional which has nil as default value. And when unwrap, it reports nil. Because IT IS a nil. You should create a empty structure and pass it to the function. Try following one.

    var buffer:vImage_Buffer = vImage_Buffer()
    ........
    vImageBuffer_InitWithCGImage(&buffer, &format, nil , sunset.CGImage, 0)
    ........


回答2:

Just create a dummy vImage_Buffer object before the call:

var buf = vImage_Buffer(data: nil, height: 0, width: 0, rowBytes: 0)

and then call:

vImageBuffer_InitWithCGImage(&buffer, ... )

and vImage will fill in all the struct fields correctly for you.



回答3:

Ok so I didn't found a way to did exectly what I wanted and its to use the vImageBuffer_initWithCGImage but thanks to good people here I did a workaround by initializing the vImage_Buffer semi manually via CGImage. Thats how my function looks like:

    func initvImageBufferwithUIImage (image:UIImage)-> vImage_Buffer{

    var CGImgRef:CGImageRef = image.CGImage
    var inProvider:CGDataProviderRef = CGImageGetDataProvider(CGImgRef)
    var inBitmapData:CFDataRef = CGDataProviderCopyData(inProvider)
    var buffer:vImage_Buffer = vImage_Buffer(data: &inBitmapData, height:
  CGImageGetHeight(CGImgRef), width: CGImageGetWidth(CGImgRef), rowBytes:
  CGImageGetBytesPerRow(CGImgRef))

    return buffer

}