在扩展中使用 CIImage 初始报告 EXC_BAD_INSTRUCTION 错误 - swift
Using CIImage initial report EXC_BAD_INSTRUCTION error in extension - swift
在问这个问题之前,我搜索了相关的post:
"unrecognized selector" when attempting to access CIFilter's outputImage
不知道是因为用了swift
还是extension
,我会得到error
。我已经测试了两个 methods
以获得 CIImage
,但在 EXC_BAD_INSTRUCTION
:
中失败
注意
我的url
不是http://
前缀,而是weixin://wxpay/bizpayurl?pr=ZwBVaW0
,我想这不是错误的原因。
方法一:
扩展字符串{
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
}
}
方法二:
扩展字符串{
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
}
}
两个方法这里都会报EXC_BAD_INSTRUCTION
错误,可以看annotation
我在报错行后面写的
编辑 - 1
我在我的项目中又试过了,没有使用extension
,还有error
,data
不是nil
:
我认为数据是nil
。
let data:Data = self.data(using: String.Encoding.utf8)!
另外一个用 CIImage
实例化的 UIImage
没有位图,它没有实际图像,它只是一组应用滤镜的指令。因此,您转换为 UIImage 的方法不应该起作用。
终于找到了一个过时的方法来生成QR code
,经过我的改进,变成了这样:
// 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
}
在问这个问题之前,我搜索了相关的post:
"unrecognized selector" when attempting to access CIFilter's outputImage
不知道是因为用了swift
还是extension
,我会得到error
。我已经测试了两个 methods
以获得 CIImage
,但在 EXC_BAD_INSTRUCTION
:
注意
我的url
不是http://
前缀,而是weixin://wxpay/bizpayurl?pr=ZwBVaW0
,我想这不是错误的原因。
方法一:
扩展字符串{
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 }
}
方法二:
扩展字符串{
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 }
}
两个方法这里都会报EXC_BAD_INSTRUCTION
错误,可以看annotation
我在报错行后面写的
编辑 - 1
我在我的项目中又试过了,没有使用extension
,还有error
,data
不是nil
:
我认为数据是nil
。
let data:Data = self.data(using: String.Encoding.utf8)!
另外一个用 CIImage
实例化的 UIImage
没有位图,它没有实际图像,它只是一组应用滤镜的指令。因此,您转换为 UIImage 的方法不应该起作用。
终于找到了一个过时的方法来生成QR code
,经过我的改进,变成了这样:
// 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
}