iosswiftciimage

Using CIImage initial report EXC_BAD_INSTRUCTION error in extension - swift


Before I asking this question, I have searched the related post:

"unrecognized selector" when attempting to access CIFilter's outputImage

I don't know if is because of using swift or extension, I will get error. I have tested two methods to get the CIImage, but fails in EXC_BAD_INSTRUCTION:

Attention
my url is not http:// prefix, but weixin://wxpay/bizpayurl?pr=ZwBVaW0, and I think this is not the reason of the error.

  1. Method one:

    extension String {

     func initQRImage() ->UIImage {
    
         let filter:CIFilter = CIFilter.init(name: "CIQRCodeGenerator")!
         filter.setDefaults()
         let data:Data = self.data(using: String.Encoding.utf8)!
         filter.setValue(data, forKey: "inputMessage")
         let outputImage:CGImage = filter.outputImage as! CGImage // EXC_BAD_INSTRUCTION here
         let qr_image = UIImage.init(cgImage: outputImage)
    
         return qr_image
     }
    

    }

  2. Method two:

    extension String {

     func initQRImage() ->UIImage {
    
         let url:URL = URL.init(fileURLWithPath: self)
         let inputImage:CIImage = CIImage.init(contentsOf: url)!  // EXC_BAD_INSTRUCTION here
         let filter: CIFilter = CIFilter.init(name: "CIAreaAverage")!
         filter.setValue(inputImage, forKey: kCIInputImageKey)
         let inputExtent:CGRect = inputImage.extent
         let extent:CIVector = CIVector.init(x: inputExtent.origin.x, y: inputExtent.origin.y, z: inputExtent.size.width, w: inputExtent.size.height)
         filter.setValue(extent, forKey: kCIInputExtentKey)
         let outputImage:CIImage = filter.value(forKey: "outputImage") as! CIImage
    
         let qr_image = UIImage.init(cgImage: outputImage as! CGImage)
         return qr_image
     }
    

    }

Two method will report EXC_BAD_INSTRUCTION error here, you can see the annotation I write after the report error line.


EDIT - 1

I have tried in my project again, not using extension, there is the error too, and data is not nil:


Solution

  • Finally I found a outdated method to generate QR code, after my improvement, it becomes this:

    // quality can modify the defintion
    class func generateQRImage(stringQR:NSString, withSizeRate rate:CGFloat, quality:CGFloat?) -> UIImage
    {
        let filter:CIFilter = CIFilter(name:"CIQRCodeGenerator")!
        filter.setDefaults()
    
        let data:NSData = stringQR.data(using: String.Encoding.utf8.rawValue)! as NSData
        filter.setValue(data, forKey: "inputMessage")
    
        let outputImg:CIImage = filter.outputImage!
    
        let context:CIContext = CIContext(options: nil)
    
        var tmp_quality = quality
    
        if quality == nil {
    
            tmp_quality = 1.0
        }
    
        let transform: CGAffineTransform  = CGAffineTransform(scaleX: tmp_quality!, y: tmp_quality!);
        let outputImg_after = outputImg.applying(transform)
    
        let cgimg:CGImage = context.createCGImage(outputImg_after, from: outputImg_after.extent)!
    
        var img:UIImage = UIImage(cgImage: cgimg, scale: 1.0, orientation: UIImageOrientation.up)
    
        let width  = img.size.width * rate
        let height = img.size.height * rate
    
        UIGraphicsBeginImageContext(CGSize.init(width: width, height: height))
        let cgContxt:CGContext = UIGraphicsGetCurrentContext()!
        cgContxt.interpolationQuality = .high // cgContxt kCGInterpolationNone
        img.draw(in: CGRect.init(x: 0, y: 0, width: width, height: height))  // (0, 0, width, height)
        img = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return img
    }