A bitmap graphics context accepts a pointer to a memory buffer that contains storage space for the bitmap. When you paint into the bitmap graphics context, the buffer is updated. After you release the graphics context, you have a fully updated bitmap in the pixel format you specify.
Note: Bitmap graphics contexts are sometimes used for drawing offscreen. Before you decide to use a bitmap graphics context for this purpose, see “CGLayer Drawing.” CGLayer objects (CGLayerRef), available in Mac OS X v10.4 and later, are optimized for offscreen drawing because, whenever possible, Quartz caches layers on the video card.
You use the function CGBitmapContextCreate to create a bitmap graphics context. This function takes the following parameters:
data. Supply a pointer to the destination in memory where you want the drawing rendered. The size of this memory block should be at least (bytesPerRow*height) bytes.
width. Specify the width, in pixels, of the bitmap.
height. Specify the height, in pixels, of the bitmap.
bitsPerComponent. Specify the number of bits to use for each component of a pixel in memory. For example, for a 32-bit pixel format and an RGB color space, you would specify a value of 8 bits per component. See “Supported Pixel Formats.”
bytesPerRow. Specify the number of bytes of memory to use per row of the bitmap.
colorspace. The color space to use for the bitmap context. You can provide a Gray, RGB, CMYK, or NULL color space when you create a bitmap graphics context. For detailed information on color spaces and color management principles, see Color Management Overview. For information on creating and using color spaces in Quartz, see “Color and Color Spaces.” For information about supported color spaces, see “Color Spaces and Bitmap Layout” in the “Bitmap Images and Image Masks” chapter.
bitmapInfo. Bitmap layout information, expressed as a CGImageBitmapInfo constant in Mac OS X v10.4, that specifies whether the bitmap should contain an alpha component, the relative location of the alpha component (if there is one) in a pixel, whether the alpha component is premultiplied, and whether the color components are integer or floating point values. (In earlier versions of Mac OS X, this constant is expressed as a CGImageAlphaInfo constant.) For detailed information on what these constants are, when each is used, and Quartz-supported pixel formats for bitmap graphics contexts and images, see “Color Spaces and Bitmap Layout” in the “Bitmap Images and Image Masks” chapter.
Listing 2-8 shows how to create a bitmap graphics context. When you draw into the resulting bitmap graphics context, Quartz records your drawing as bitmap data in the specified block of memory. A detailed explanation for each numbered line of code follows the listing.
Listing 2-8 A routine that creates a bitmap graphics context
CGContextRef MyCreateBitmapContext (int pixelsWide, |
int pixelsHigh) |
{ |
CGContextRef context = NULL; |
CGColorSpaceRef colorSpace; |
void * bitmapData; |
int bitmapByteCount; |
int bitmapBytesPerRow; |
bitmapBytesPerRow = (pixelsWide * 4);// 1 |
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); |
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2 |
bitmapData = malloc( bitmapByteCount );// 3 |
if (bitmapData == NULL) |
{ |
fprintf (stderr, "Memory not allocated!"); |
return NULL; |
} |
context = CGBitmapContextCreate (bitmapData,// 4 |
pixelsWide, |
pixelsHigh, |
8, // bits per component |
bitmapBytesPerRow, |
colorSpace, |
kCGImageAlphaPremultipliedLast); |
if (context== NULL) |
{ |
free (bitmapData);// 5 |
fprintf (stderr, "Context not created!"); |
return NULL; |
} |
CGColorSpaceRelease( colorSpace );// 6 |
return context;// 7 |
} |
Here’s what the code does:
Declares a variable to represent the number of bytes per row. Each pixel in the bitmap in this example is represented by 4 bytes; 8 bits each of red, green, blue, and alpha.
Creates a generic RGB color space. You can also create a CMYK color space. See “Color and Color Spaces” for more information and for a discussion of generic color spaces versus device dependent ones.
Calls the malloc function to create a block of memory in which to store the bitmap data. This example creates a 32-bit RGBA bitmap (that is, an array with 32 bits per pixel, each pixel containing 8 bits each of red, green, blue, and alpha information). Each pixel in the bitmap occupies 4 bytes of memory.
Creates a bitmap graphics context, supplying the bitmap data, the width and height of the bitmap, the number of bits per component, the bytes per row, the color space, and a constant that specifies whether the bitmap should contain an alpha channel and its relative location in a pixel. The constant kCGImageAlphaPremultipliedLast indicates that the alpha component is stored in the last byte of each pixel and that the color components have already been multiplied by this alpha value. See “The Alpha Value” for more information on premultiplied alpha.
If the context isn’t created for some reason, frees the memory allocated for the bitmap data.
Releases the color space.
Returns the bitmap graphics context. The caller must release the graphics context when it is no longer needed.
Listing 2-9 shows code that calls MyCreateBitmapContext to create a bitmap graphics context, uses the bitmap graphics context to create a CGImage, then draws the resulting image to a window graphics context. Figure 2-7 shows the image drawn to the window. A detailed explanation for each numbered line of code follows the listing.
Listing 2-9 Code that draws to a bitmap graphics context
CGRect myBoundingBox;// 1 |
myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);// 2 |
myBitmapContext = MyCreateBitmapContext (400, 300);// 3 |
// ********** Your drawing code here ********** // 4 |
CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1); |
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 )); |
CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5); |
CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 )); |
myImage = CGBitmapContextCreateImage (myBitmapContext);// 5 |
CGContextDrawImage(myContext, myBoundingBox, myImage);// 6 |
char *bitmapData = CGBitmapContextGetData(myBitmapContext); // 7 |
CGContextRelease (myBitmapContext);// 8 |
if (bitmapData) free(bitmapData); // 9 |
CGImageRelease(myImage);// 10 |
Here’s what the code does:
Declares a variable to store the origin and dimensions of the bounding box into which Quartz will draw an image created from the bitmap graphics context.
Sets the origin of the bounding box to (0,0) and the width and height to variables previously declared, but whose declaration are not shown in this code.
Calls the application supplied function MyCreateBimapContext (see Listing 2-8) to create a bitmap context that is 400 pixels wide and 300 pixels high. You can create a bitmap graphics context using any dimensions that are appropriate for your application.
Calls Quartz 2D functions to draw into the bitmap graphics context. You would replace this and the next four lines of code with drawing code appropriate for your application.
Creates a Quartz 2D image (CGImageRef) from the bitmap graphics context. The function CGBitmapContextCreateImage is available in Mac OS X v10.4 and later. For information on creating Quartz 2D images from a bitmap graphics context in earlier versions of Mac OS X, see “Bitmap Images and Image Masks.”
Draws the image into the location in the window graphics context that is specified by the bounding box. The bounding box specifies the location and dimensions in user space in which to draw the image.
This example does not show the creation of the window graphics context. See “Creating a Window Graphics Context” for information on how to create one.
Gets the bitmap data associated with the bitmap graphics context.
Releases the bitmap graphics context when it is no longer needed.
Free the bitmap data if it exists.
Releases the image when it is no longer needed.
Supported Pixel Formats
Anti-Aliasing
Table 2-1 summarizes the pixel formats that are supported for bitmap graphics context, the associated color space (cs), and the format availability in versions of Mac OS X. The pixel format is specified as bits per pixel (bpp) and bits per component (bpc). The table also includes the bitmap information constant associated with that pixel format. See CGImage Reference for details on what each of the bitmap information format constants represent.
CS | Pixel Format and Bitmap Information Constant | Availability |
|---|---|---|
Gray | 8 bpp, 8 bpc, | 10.0 |
Null | 8 bpp, 8 bpc, | 10.3 |
RGB | 16 bpp, 5 bpc, | 10.0 |
RGB | 32 bpp, 8 bpc, | 10.0 |
RGB | 32 bpp, 8 bpc, | 10.0 |
RGB | 32 bpp, 8 bpc, | 10.0 |
RGB | 32 bpp, 8 bpc, | 10.0 |
CMYK | 32 bpp, 8 bpc, | 10.3 |
Gray | 32 bpp, 32 bpc, | 10.4 |
RGB | 128 bpp, 32 bpc, | 10.4 |
RGB | 128 bpp, 32 bpc, | 10.4 |
CMYK | 128 bpp, 32 bpc, | 10.4 |
Gray | 16 bpp, 16 bpc, | 10.5 |
RGB | 64 bpp, 16 bpc, | 10.5 |
RGB | 64 bpp, 16 bpc, | 10.5 |
CMYK | 64 bpp, 16 bpc, | 10.5 |
Bitmap graphics contexts support anti-aliasing, which is the process of artificially correcting the jagged (or aliased) edges you sometimes see in bitmap images when text or shapes are drawn. These jagged edges occur when the resolution of the bitmap is significantly lower than the resolution of your eyes. To make objects appear smooth in the bitmap, Quartz uses different colors for the pixels that surround the outline of the shape. By blending the colors in this way, the shape appears smooth. You can see the effect of using anti-aliasing in Figure 2-8. You can turn anti-aliasing off for a particular bitmap graphics context by calling the function CGContextSetShouldAntialias. The anti-aliasing setting is part of the graphics state.
As of Mac OS X v10.4 you can control whether or not to allow anti-aliasing for a particular graphics context by using the function CGContextSetAllowsAntialiasing. Pass true to this function to allow anti-aliasing; false not to allow it. This setting is not part of the graphics state. Quartz performs anti-aliasing for a graphics context if you allow anti-aliasing by passing true to CGContextSetAllowsAntialiasing and you set the anti-aliasing graphics state parameter to true by calling CGContextSetShouldAntialias.
Last updated: 2007-12-11