Image I/OImage I/O is part of Core Graphics and follows the Core Graphics API conventions. Strictly speaking, it is not part of Quartz 2D, but it does integrate closely with Quartz 2D and is an invaluable asset. The two primary opaque data types that make up the Image I/O system are CGImageSource and CGImageDestination. The CGImageSource class represents an abstract source for image data. Conceptually, the image source contains one or more images. An image file, a network stream, or a block of memory are all valid image sources. Each CGImageSource knows how to extract images from a particular source. After creating a CGImageSource, you can ask it to return any of those images as a CGImageRef. Not surprisingly, the CGImageDestination represents an object that knows how to take one or more CGImages, encode them in a particular format, and store the results, or even transfer them elsewhere. After creating an image destination attached to a storage device, your application can pass it one or more images and then ask the destination to encode and save the graphics. The image source and image destination classes don't concern themselves with the details of interacting with the file system or the network. Instead the CGImageSource opaque data type uses the familiar CGDataProvider opaque data type that we explored when creating images, and CGImageDestination uses its companion, the CGDataConsumer opaque data type. These objects offer your application a lot of flexibility in deciding where the image data is coming from. It can read from the network or from a local file, or it can generate the image data on-the-fly if that makes sense. Import Image ExampleThe first sample will demonstrate using a CGImageSource. This code performs the same task as the QuickTime example earlier in the chapter. It is included with the sample code as part of an application called ImageIOImport. Listing 9.3 recreates the image import routine from listing 9.1 using a CGImageSource instead of a QuickTime import component: Listing 9.3. Importing an Image with a CGImageSource
This code sample demonstrates the basic technique of using an image source. It first creates a data provider that points to the image data we want to import. It then creates a data source from that data provider. With the data source in hand, the code simply asks for the first image in that source (the images are indexed starting at 0). When the image has been imported, the computer creates a window to display the results.
Image I/O includes additional functionality related to the loading of images. Of particular interest may be the fact that it can retrieve image thumbnails from file formats that provide them, and it supports the incremental loading of large images. Those topics will not be covered here, but you can read more about them in Apple's documentation. Export Image ExampleIt's just as easy to export an image using Image I/O as it is to read one in. By now the process should be pretty obvious. The duality of creating a CGDataProvider for an image import operation is creating a CGDataConsumer for the results of compressing an image. The CGDataConsumer is responsible for taking the compressed image data and doing something with it, be it storing the data on a disk or writing it into a block of memory. Once you've decided what to do with the image data, you create a CGImageDestination that connects to the data consumer. You can pass the images you want to store in the destination to that object, and the system will handle compressing the image and shipping it off to the data consumer. Listing 9.4 demonstrates the technique of writing a CGImage into a file using a CGImageDestination. Listing 9.4. Exporting an Image Using Image I/O
One interesting point to note about this code sample and Image I/O is that you specify the type of file you want to export using a Uniform Type Identifier (UTI). In this case the UTI we use is kUTTypePng. Uniform Type Identifiers are a mechanism for specifying the type of various and sundry things that have distinguishable types. That's a bit of a vague description for an odd concept. In this case there are a number of different types of files you might export to using Image I/O. You use image file type UTIs to tell Image I/O what type of file you want to use. For more information on UTI's, you can read Apple's documentation on the subject at <http://developer.apple.com/documentation/Carbon/Conceptual/understanding_utis/understand_utis_intro/chapter_1_section_1.html> Note that after adding the image, the code calls CGImageDestinationFinalize. If you do not call this method, the computer may not finish writing the data to the output properly. Also once you have called this routine, you will be unable to add more files to the CGImageDestination. |