You've just seen the basic steps an application goes through to use Core Image. Now you'll see some of the details by looking at sample code. This code sample builds and renders the CIImage that applies a Gaussian blur to an image. The results of the Gaussian blur are illustrated in Figure 10.1. Figure 10.1. The Image Before and After Blurring In this case Core Image has been asked to take the lovely beach image and apply a Gaussian Blur filter with a radius of 10. This complete code sample is called CoreImageBasics and is a Carbon application that simply displays the blurred image in a window. The portion of the application that generates the blurred image is given in Listing 10.1. Listing 10.1. Code Using Core Image to Blur an Image
The code begins by creating an NSAutoreleasePool. This is a small concession that Carbon applications must make when working with Objective-C APIs. The autorelease pool catches objects that your application, or the operating system, might autorelease in the course of its run. If this code were running inside of a Cocoa application, the autorelease pool would be part of the main application event loop. The source code releases the autorelease pool at the bottom, which frees any autoreleased objects. For more information on using Objective-C methods from Carbon applications, please visit the Carbon-Cocoa integration guide at http://developer.apple.com/documentation/Cocoa/Conceptual/CarbonCocoaDoc/Articles/CocoaUIInCarbon.html The code calls an external routine, CreateSourceImage, that loads the beach scene from a file in the application's resources using Image I/O (see Chapter 9, "Importing and Exporting Images"). The code uses this CGImage to create a CIImage. The CIImage that it creates has a single instruction which is, essentially, "collect these specific pixels." If you were to draw this CIImage, it would do little more than draw the pixels of the CGImage. The code extracts a bounding rectangle for the CGImage as well, and at that point we're done with it. By the rules of object ownership, if the CIImage wants the CGImage any more, it should have retained it, but you're done with the image now, so you release it. The image program has been started and you're ready to filter the image. You create the CIFilter using the filterWithName method of that class. Filters are also organized into categories. Using the methods of the CIFilter class, your application can obtain lists of categories and lists of all the filters in a particular category. The built-in categories are listed in the CIFilter.h header file. You can use these routines to allow your users to create the filter of their choice. Next, the code sets the parameters for the blur filter. In writing the sample code, the input parameters for the filter in the documentation were looked up. A CIFilter also includes methods that let you ask them for a list of the input parameter keys for the filter. This might be helpful if your application wants to generate a custom UI to let the user specify values for the input parameters. The Core Image Fun House sample code mentioned earlier in the chapter demonstrates how to do this. In this case, the Gaussian blur filter accepts two parameters, an image (the image to blur) and the blur radius. Blur radius is simply a value that indicates how blurry you want the image to be. CIFilters use an Objective-C programming technique called "key-value coding" to change the input parameters of the filter. Essentially this means that your code sets the input parameters by name. The method setValue:forKey: is used here to establish the CIImage that is the input to the filter, as well as the inputRadius for the blur filter.
At this point, you are ready to construct the CIImage that contains both drawing commands. To do this, you ask the filter for its outputImage property, again using the techniques of key-value coding. This property combines the input parameters and generates a new CIImage. This new CIImage knows how to draw the results of applying that filter. The final step of the sample draws the results of the filtering step into the CGContext that was passed to the routine as a parameter. To draw on the CGContext you have to first create a CIContext that the computer will execute the CIImage's image program in. You can use the contextWithCGContext: method of CIContext to create an appropriate drawing environment and then ask that environment to draw the CIImage. This sample code runs through all these steps every time the computer wants to draw the image. Ideally, however, the code would cache the CIImage retrieved from the Gaussian blur filter and reuse it to draw the same image each time it was asked to. |