Marcel
Marcel

Reputation: 131

iOS CIFilters which actually do work?

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

Answers (1)

rob mayoff
rob mayoff

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

Related Questions