UIImage vs CIImage vs CGImage
2017-09-07 18:45
267 查看
公司项目中需要对图片进行滤镜处理,故学习了ios CoreImage中CIFilter相关知识。
出现了一个奇怪的问题,如果下面这么写的话,会出现野指针EXC_BAD_ACCESS的情况,通过ZombieObject定位到是在使用滤镜输出的UIImage给UIImageView.image赋值的时候出现的崩溃。
这种方式是UIImage转换成CIImage,滤镜处理后,直接转回UIImage。
经过查询苹果开发者网站和Github上的滤镜使用实例后,改为下面的方法,没有发生崩溃。
区别有二:
1,UIImage->CIImage的方式,改为直接创建
2,CIImage->UIImage的方式,改为CIImage->CGImage->UIImage。
解释一下CIImage CGImage UIImage的区别:
UIImage是显示图像数据的高层方式。可以从文件,或者原始图像数据生成UIImage对象。这些数据在初始化时就不可变了。
CIImage对象也是线程安全的,它并不是一张图片。它包含了所有生成一张图片所有的必要信息。CIImage对象通常用在CIFilter, CIContext, CIColor, CIVector。跟GPU的处理相关。
CGImage,只能表示位图。如果需要访问和改变实际的位图数据的话,可以用CGImage。
Core Image与OpenGL可互操作,可以在View的draw方法中用OpenGL来提高性能:
2017/9/14追记
由于程序上线前测试不足,上线一天后,在adoption为50%左右的情况下,还是出现了3次crash。崩溃栈信息如下:
Google到有人有类似的问题并用下面的方法解决,10K MAU上线4天没有上报崩溃。
参考:
1,https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94
2,https://objccn.io/issue-21-6/
出现了一个奇怪的问题,如果下面这么写的话,会出现野指针EXC_BAD_ACCESS的情况,通过ZombieObject定位到是在使用滤镜输出的UIImage给UIImageView.image赋值的时候出现的崩溃。
这种方式是UIImage转换成CIImage,滤镜处理后,直接转回UIImage。
//黑白效果 func noir() -> UIImage? { let imageData = UIImagePNGRepresentation(self) let inputImage = CoreImage.CIImage(data: imageData!) guard let filter = CIFilter(name:"CIPhotoEffectNoir") else {return nil} filter.setValue(inputImage, forKey: kCIInputImageKey) if let outputImage = filter.outputImage { let image = UIImage.init(ciImage: outputImage) return image } return nil }
经过查询苹果开发者网站和Github上的滤镜使用实例后,改为下面的方法,没有发生崩溃。
区别有二:
1,UIImage->CIImage的方式,改为直接创建
2,CIImage->UIImage的方式,改为CIImage->CGImage->UIImage。
func noir() -> UIImage? { let inputImage = CIImage(image: self) guard let context = CIContext.mara_context(options: nil) else {return nil} guard let filter = CIFilter(name:"CIPhotoEffectNoir") else {return nil} filter.setValue(inputImage, forKey: kCIInputImageKey) if let outputCIImage = filter.outputImage { guard let outputCGImage = context.createCGImage(outputCIImage, from: outputCIImage.extent) else {return nil} let image = UIImage(cgImage: outputCGImage) return image } return nil }
解释一下CIImage CGImage UIImage的区别:
UIImage是显示图像数据的高层方式。可以从文件,或者原始图像数据生成UIImage对象。这些数据在初始化时就不可变了。
CIImage对象也是线程安全的,它并不是一张图片。它包含了所有生成一张图片所有的必要信息。CIImage对象通常用在CIFilter, CIContext, CIColor, CIVector。跟GPU的处理相关。
CGImage,只能表示位图。如果需要访问和改变实际的位图数据的话,可以用CGImage。
Core Image与OpenGL可互操作,可以在View的draw方法中用OpenGL来提高性能:
let eaglContext = EAGLContext(API: .OpenGLES2) let ciContext = CIContext(EAGLContext: eaglContext) //滤镜处理 // ... ciContext.drawImage(filter.outputImage, inRect: outputBounds, fromRect: inputBounds)
2017/9/14追记
由于程序上线前测试不足,上线一天后,在adoption为50%左右的情况下,还是出现了3次crash。崩溃栈信息如下:
Google到有人有类似的问题并用下面的方法解决,10K MAU上线4天没有上报崩溃。
EAGLContext.setCurrent(nil) guard let context = CIContext.mara_context(options: nil) else {return nil}
参考:
1,https://medium.com/@ranleung/uiimage-vs-ciimage-vs-cgimage-3db9d8b83d94
2,https://objccn.io/issue-21-6/
相关文章推荐
- Swift之CIImage、CGImage、UIImage之间的相互转换
- CIImage CGImage UIImage 区别
- UIImage与CIImage的区别
- IOS Dev Intro - NSImage CIImage CGImage
- ios (Quartz 2D绘图) UIImage,CGImage和CGImageRef有什么区别
- 谈谈UIImage、CGImageRef、CIImage
- [UIImage imageNamed…] vs [UIImage imageWithData…]
- OC--[UIImage imageWithCGImage:]-----Swfit--UIImage.init(CGImage:)
- UIImage, CGImageRef, CIImage
- [iphone]UIImage,CGImage和CGImageRef有什么区别
- UIImage initwithCGImage 有问题,一定要注意
- UIImage方法(imageWithCGImage: scale: orientation:)
- 【IOS 开发学习总结-OC-63】UIImage 与 CGImage,CGImageRef
- data buffer与CGImage/UIImage互转
- UIImage,CGImage和CGImageRef 区别
- UIIMage与CGImage的关系
- 如何从UIImage或者CGImage获取到图片的像素数据
- UIImage CIImage CGImageRef
- UIImage和CGImage的区别
- 将一个CIImage转换为我们的UIImage