Quartz provides a variety of functions that create a CGImage object from a bitmap image. The choice of image creation function depends on the source of the image data and the version of the operating system your software needs to run in. The most flexible function is CGImageCreate. It creates an image from any kind of bitmap data and the function runs in all versions of Mac OS X. However, it’s the most complex function to use because you must specify all bitmap information. To use this function, you need to be familiar with the topics discussed in “Bitmap Image Information.”
Each version of the operating system introduces new image creation functions, as you’ll see by looking at Table 11-1. If your application runs in Mac OS X v10.4 and later, and you want to create a CGImage object from an image file that uses a standard image format such as PNG or JPEG, the easiest solution is to call the function CGImageSourceCreateWithURL to create an image source and then call the function CGImageSourceCreateImageAtIndex to create an image from the image data at a specific index in the image source. If the original image file contains only one image, then provide 0 as the index. If the image file format supports files that contain multiple images, you need to supply the index to the appropriate image, keeping in mind that the index values start at 0.
If you’ve drawn content to a bitmap graphics context and want to capture that drawing to a CGImage, call the function CGBitmapContextCreateImage. This function, like many of the functions in Table 11-1, is available only in Mac OS X v10.4.
Several functions are utilities that operate on existing images, either to make a copy, create a thumbnail, or create an image from a portion of a larger one. Regardless of how you create a CGImage object, you use the function CGContextDrawImage to draw the image to any “flavor” of graphics context. Keep in mind that CGImage objects are immutable. When you no longer need a CGImage object, release it by calling the function CGImageRelease.
Function | Description |
|---|---|
| A flexible function for creating an image. You must specify all the bitmap information that is discussed in “Bitmap Image Information.” Available in Mac OS X v10.0 and later. |
| Creates an image from a data provides that supplies JPEG-encoded data. See “Data Management” for information on creating a JPEG data provider. Available in Mac OS X v10.1 and later. |
| Creates an image from a data provider that supplies PNG-encoded data. See “Data Management” for information on creating a PNG data provider. Available in Mac OS X v10.2 and later. |
| Creates an image from the data contained within a subrectangle of an image. Available in Mac OS X v10.4 and later. |
| Creates an image from an image source. Image sources can contain more than one image. See “Data Management” for information on creating an image source. Available in Mac OS X v10.4 and later. |
| Creates a thumbnail image of an image that is associated with an image source. See “Data Management” for information on creating an image source. Available in Mac OS X v10.4 and later. |
| Creates an image by copying the bits from a bitmap graphics context. Available in Mac OS X v10.4 and later. |
| A utility function that creates a copy of an image. Available in Mac OS X v10.4 and later. |
| A utility function that creates a copy of an image and replaces its colorspace. Available in Mac OS X v10.3 and later. |
The sections that follow discuss how to create:
An image from a JPEG file using a data provider.
A subimage from an existing image.
An image from a bitmap graphics context.
You can consult these sources for additional information:
“Data Management” discusses data consumers, data providers, image sources, and image destinations, and how to use each to read and write image data.
CGImage Reference, CGImageSource Reference, and CGBitmapContext Reference for further information on the functions listed in Table 11-1 and their parameters.
Creating an Image From a JPEG File
Creating an Image From Part of a Larger Image
Creating an Image From a Bitmap Graphics Context
The function CGImageCreate creates a CGImage object from bitmap image information that you supply (discussed in “Bitmap Image Information”). If the bitmap image uses JPEG- or PNG-encoded data, it’s much easier to use the convenience functions CGImageCreateWithJPEGDataProvider or CGImageCreateWithPNGDataProvider. If your code runs in Mac OS X v10.4 and later, you also have the option of creating an image source from a URL using CGImageSourceCreateWithURL and then create an image from the image source by calling the function CGImageSourceCreateImageAtIndex. The image at the URL location can be one of any number of formats, including PNG, TIFF, JPEG, JPEG2000, and GIF.
Listing 11-1 shows a function that creates a CGImage object with data that is supplied by a JPEG data provider, and then draws the image to a graphics context passed to the function. Quartz uses its knowledge of the JPEG file format to decode the file and create a CGImage object from it. The code in this listing works in Mac OS X v10.1 and later. A detailed explanation for each numbered line of code appears following the listing.
Listing 11-1 A function that creates a CGImage object from a JPEG file
void MyCreateAndDrawBitmapImage (CGContextRef myContext, // 1 |
CGRect myContextRect, |
const char *filename); |
{ |
CGImageRef image; |
CGDataProviderRef provider; |
CFStringRef path; |
CFURLRef url; |
path = CFStringCreateWithCString (NULL, filename, |
kCFStringEncodingUTF8); |
url = CFURLCreateWithFileSystemPath (NULL, path, // 2 |
kCFURLPOSIXPathStyle, NULL); |
CFRelease(path); |
provider = CGDataProviderCreateWithURL (url);// 3 |
CFRelease (url); |
image = CGImageCreateWithJPEGDataProvider (provider,// 4 |
NULL, |
true, |
kCGRenderingIntentDefault); |
CGDataProviderRelease (provider);// 5 |
CGContextDrawImage (myContext, myContextRect, image);// 6 |
CGImageRelease (image);// 7 |
} |
Here’s what the code does:
Takes as parameters a graphics context, the rectangle to draw into, and a filename.
Calls the Core Foundation function for creating a CFURL object that specifies the location of the file to open.
Creates a data provider object from the CFURL object. See “Data Management” for information on data providers.
Creates a CGImage object from the data provider. If you don’t need to map color component values to another range, you can pass NULL for the decode array, as in this example. In most cases, you should pass true to turn on interpolation. The constant kCGRenderingIntentDefault specifies that Quartz use the default for the graphics context.
Releases the data provider when it is no longer needed.
Draws the bitmap image to the graphics context supplied, drawing into the area specified by the myContextRect rectangle.
Releases the CGImage object when it is no longer needed.
The function CGImageCreateWithImageInRect lets you create a subimage from an existing Quartz image. Figure 11-3 illustrates extracting an image that contains the letter “A” from a larger image by supplying a rectangle that specifies the location of the letter “A”.
The image returned by the function CGImageCreateWithImageInRect retains a reference to the original image, which means you can release the original image after calling this function.
Figure 11-4 shows another example of extracting a portion of an image to create another image. In this case, the rooster’s head is extracted from the larger image, and then drawn to a rectangle that’s larger than the subimage, effectively zooming-in on the image.
Listing 11-2 shows code that creates and then draws the subimage. The rectangle that the function CGContextDrawImage draws the rooster’s head to has dimensions that are twice the dimensions of the extracted subimage. The listing is a code fragment. You’d need to declare the appropriate variables, create the rooster image, and dispose of the rooster image and the rooster head subimage. Because the code is a fragment, it does not show how to create a the graphics context that the image is drawn to. You can use an flavor of graphics context that you’d like. For examples of how to create a graphics context, see “Graphics Contexts.”
Listing 11-2 Code that creates a subimage and draws it enlarged
myImageArea = CGRectMake (rooster_head_x_origin, rooster_head_y_origin, |
myWidth, myHeight); |
mySubimage = CGImageCreateWithImageInRect (myRoosterImage, myImageArea); |
myRect = CGRectMake(0, 0, myWidth*2, myHeight*2); |
CGContextDrawImage(context, myRect, mySubimage); |
To create an image from an exiting bitmap graphics context, you call the function CGBitmapContextCreateImage as follows:
CGImageRef myImage; |
myImage = CGBitmapContextCreateImage (myBitmapContext); |
The CGImage object returned by the function is created by a copy operation. This means that any subsequent changes you make to the bitmap graphics context do not affect the contents of the returned CGImage. In some cases the copy operation actually follows copy-on-write semantics, so that the actual physical copy of the bits occurs only if the underlying data in the bitmap graphics context is modified. You may want to use the resulting image and release it before you perform additional drawing into the bitmap graphics context so that you can avoid the actual physical copy of the data.
For an example that shows how to create a bitmap graphics context, see“Creating a Bitmap Graphics Context.”
Last updated: 2007-12-11