Reputation: 131
I am currently trying to populate a collection view with a picture which is filtered by different CIFilters. I used apples way to get an array of filters.
let filterNames = CIFilter.filterNamesInCategories([kCICategoryStillImage,kCICategoryBuiltIn])
I thought this should give me all filters which are applicable to still images on the iPhone. But it kinda doesn't work.
This are (some) of the filters i get from the method above:
["CIAccordionFoldTransition", "CIAdditionCompositing", "CIAffineClamp", "CIAffineTile", "CIAffineTransform", "CIAreaAverage", "CIAreaHistogram", "CIAreaMaximum", "CIAreaMaximumAlpha", "CIAreaMinimum", "CIAreaMinimumAlpha", "CIAztecCodeGenerator", "CIBarsSwipeTransition", "CIBlendWithAlphaMask", "CIBlendWithMask", "CIBloom", "CIBoxBlur", "CIBumpDistortion", "CIBumpDistortionLinear", "CICheckerboardGenerator", "CICircleSplashDistortion", "CICircularScreen", "CICircularWrap", "CICMYKHalftone",
plus A LOT more.
I apply the filters with this method:
func applyFilter(image: UIImage, filterName: String) -> UIImage {
let beginImage = CIImage(CGImage: image.CGImage!)
let filter = CIFilter(name: filterName)!
filter.setValue(beginImage, forKey: kCIInputImageKey)
filter.setDefaults()
let context = CIContext(options: nil)
let imageRef = context.createCGImage(filter.outputImage!, fromRect: beginImage.extent)
let newImage = UIImage(CGImage: imageRef)
return newImage
}
The first two filters wont work because the resulting image is a nil, then some work, and then i get:
[<CIAztecCodeGenerator 0x7fb89c775460> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputImage.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010cd5de65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010efebdeb objc_exception_throw + 48
2 CoreFoundation 0x000000010cd5daa9 - [NSException raise] + 9
3 CoreImage 0x000000010d33eea2 -[CIFilter setValue:forUndefinedKey:] + 137
4 CoreImage 0x000000010d4093ce -[CIAztecCodeGenerator setValue:forUndefinedKey:] + 335
5 Foundation 0x000000010d6749bb -[NSObject(NSKeyValueCoding) setValue:forKey:] + 288
6 DrawIt 0x000000010cb55088 _TFC6DrawIt25applyFilterViewController11applyFilterfS0_FTCSo7UIImage10filterNameSS_S1_ + 552
7 DrawIt 0x000000010cb54b52 _TFC6DrawIt25applyFilterViewController14collectionViewfS0_FTCSo16UICollectionView22cellForItemAtIndexPathCSo11NSIndexPath_CSo20UICollectionViewCell + 1186
8 DrawIt 0x000000010cb54e3f _TToFC6DrawIt25applyFilterViewController14collectionViewfS0_FTCSo16UICollectionView22cellForItemAtIndexPathCSo11NSIndexPath_CSo20UICollectionViewCell + 79
9 UIKit 0x000000010e31d5ba -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:] + 483
10 UIKit 0x000000010e31fae0 -[UICollectionView _updateVisibleCellsNow:] + 4431
11 UIKit 0x000000010e32423b -[UICollectionView layoutSubviews] + 247
12 UIKit 0x000000010db7f4a3 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703
13 QuartzCore 0x0000000113d0059a -[CALayer layoutSublayers] + 146
14 QuartzCore 0x0000000113cf4e70 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
15 QuartzCore 0x0000000113cf4cee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
16 QuartzCore 0x0000000113ce9475 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
17 QuartzCore 0x0000000113d16c0a _ZN2CA11Transaction6commitEv + 486
18 QuartzCore 0x0000000113d259f4 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 576
19 CoreFoundation 0x000000010ccbdc84 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
20 CoreFoundation 0x000000010ccbd831 __CFRunLoopDoTimer + 1089
21 CoreFoundation 0x000000010cc7f241 __CFRunLoopRun + 1937
22 CoreFoundation 0x000000010cc7e828 CFRunLoopRunSpecific + 488
23 GraphicsServices 0x0000000113bc8ad2 GSEventRunModal + 161
24 UIKit 0x000000010dac8610 UIApplicationMain + 171
25 DrawIt 0x000000010cb569fd main + 109
26 libdyld.dylib 0x000000010faf492d start + 1
27 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I did not check all the rest of the filters. I thought that the array SHOULD only contain flters which are applicable easy as that. Is it the code thats wrong or the array of Filters I use?
But e.g. the first Filter (CIAccordionFoldTransition) seems to be a transition not really a filter. So it makes sense that it has a nil as output.
Is there a way to get all filters which are applicable to a single picture just like that?
I am pretty fresh in iOs and I hope my question isn't to stupid for this homepage, be kind! Greetings and thanks in advance.
Upvotes: 3
Views: 1286
Reputation: 386018
Some of the filters returned by CIFilter.filterNamesInCategories
have an inputImage
attribute, and some do not.
For example, the attributes understood by CIAztecCodeGenerator
(mentioned in your exception report) are listed here, and inputImage
isn't one of them.
A filter reports the keys for its input attributes through its inputKeys
property. It describes all of its attributes through its attributes
property.
Perhaps you want to restrict your filters to those that have an inputImage
attributes:
let filterNames = CIFilter.filterNamesInCategories([kCICategoryStillImage,kCICategoryBuiltIn])
.filter { CIFilter(name: $0)?.inputKeys.contains("inputImage") ?? false }
Upvotes: 5