Drawing Text with Quartz 2D; The Text Processing Pipeline; Drawing Text; Drawing Simple Strings; Drawing with Glyphs; A Drawing Sample; Chapter 12. Drawing Offscreen; Using a CGBitmapContext; Working with CGLayers; A Layer Drawing Example; Chapter 13. Shadings and Patterns; Shadings; Creating Shadings; Patterns; Creating Patterns; Drawing with Patterns; Chapter 14. Working with PDF; Drawing PDF.
![]()
Learn SwiftUI and take your iOS Development to the Next LevelSwiftUI Essentials – iOS Edition book is now available in Print ($37.99) and eBook ($29.99) editions.As previously discussed in Drawing iOS 5 iPad 2D Graphics with Quartz, the Quartz 2D API is the primary mechanism by which 2D drawing operations are performed within iOS 5 iPad applications. Having provided an overview of Quartz 2D as it pertains to iOS development for the iPad in that chapter, the focus of this chapter is to provide a tutorial that provides examples of how 2D drawing is performed.
If you are new to Quartz 2D and have not yet read Drawing iOS 5 iPad 2D Graphics with Quartz it is recommended that you do so now before embarking on this tutorial. Creating the UIView SubclassIn order to draw graphics on the view it is necessary create a subclass of the UIView object and override the drawRect method. In the project navigator panel located on the left hand side of the main Xcode window Ctrl-click on the draw2D folder entry and select New File from the resulting menu.
In the New File window, select the Objective-C class icon and click Next. On the subsequent options screen, change the Subclass of: menu to UIView and the class name to draw2D. Click Next and on the final screen click on the Create button.Select the draw2DViewController.xib file and select the UIView component in the View object. Display the Identity Inspector ( View - Utilities - Show Identity Inspector) and change the Class setting from UIView to our new class named draw2D.
Bitmap Images and Image MasksBitmap images and image masks are like any drawing primitive in Quartz. Both images and image masks in Quartz are represented by the CGImageRef data type. As you’ll see later in this chapter, there are a variety of functions that you can use to create an image.
Some of them require a data provider or an image source to supply bitmap data. Other functions create an image from an existing image either by copying the image or by applying an operation to the image. No matter how you create a bitmap image in Quartz, you can draw the image to any flavor of graphics context. Keep in mind that a bitmap image is an array of bits at a specific resolution. If you draw a bitmap image to a resolution-independent graphics context (such as a PDF graphics context) the bitmap is limited by the resolution at which you created it.There is one way to create a Quartz image mask—by calling the function CGImageMaskCreate. You’ll see how to create one in. Applying an image mask is not the only way to mask drawing.
The sections, and discuss all the masking methods available in Quartz. About Bitmap Images and Image MasksA bitmap image (or sampled image) is an array of pixels (or samples).
Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.
Application icons are bitmap images. Bitmap images are restricted to rectangular shapes. But with the use of the alpha component, they can appear to take on a variety of shapes and can be rotated and clipped, as shown in Figure 11-1. Figure 11-1 Bitmap imagesEach sample in a bitmap contains one or more color components in a specified color space, plus one additional component that specifies the alpha value to indicate transparency. Each component can be from 1 to as many as 32 bits.
In Mac OS X, Quartz also provides support for floating-point components. The supported formats in Mac OS X and iOS are described in. ColorSync provides color space support for bitmap images.Quartz also supports image masks. An image mask is a bitmap that specifies an area to paint, but not the color. In effect, an image mask acts as a stencil to specify where to place color on the page. Quartz uses the current fill color to paint an image mask.
An image mask can have a depth of 1 to 8 bits. Bitmap Image InformationQuartz supports a wide variety of image formats and has built-in knowledge of several popular formats. In iOS, the formats include JPEG, GIF, PNG, TIF, ICO, GMP, XBM, and CUR. Other bitmap image formats or proprietary formats require that you specify details about the image format to Quartz in order to ensure that images are interpreted correctly.
The image data you supply to the function CGImageCreate must be interleaved on a per pixel, not a per scan line, basis. Quartz does not support planar data.This section describes the information associated with a bitmap image. When you create and work with Quartz images (which use the CGImageRef data type), you’ll see that some Quartz image-creation functions require you to specify all this information, while other functions require a subset of this information.
What you provide depends on the encoding used for the bitmap data, and whether the bitmap represents an image or an image mask. Note: For the best performance when working with raw image data, use the vImage framework. You can import image data to vImage from a CGImageRef reference with the vImageBufferInitWithCGImage function. For details, see.Quartz uses the following information when it creates a bitmap image ( CGImageRef):.A bitmap data source, which can be a Quartz data provider or a Quartz image source. Describes both and discusses the functions that provide a source of bitmap data.An optional decode array ( ).An interpolation setting, which is a Boolean value that specifies whether Quartz should apply an interpolation algorithm when resizing the image.A rendering intent that specifies how to map colors that are located within the destination color space of a graphics context. This information is not needed for image masks.
![]()
See for more information.The image dimensions.The pixel format, which includes bits per component, bits per pixel, and bytes per row ( ).For images, color spaces and bitmap layout ( ) information to describe the location of alpha and whether the bitmap uses floating-point values. Image masks don’t require this information.Decode ArrayA decode array maps the image color values to other color values, which is useful for such tasks as desaturating an image or inverting the colors. The array contains a pair of numbers for each color component. When Quartz renders the image, it applies a linear transform to map the original component value to a relative number within the designated range appropriate for the destination color space. For example, the decode array for an image in the RGB color space contains six entries, one pair for each red, green, and blue color component. Pixel FormatThe pixel format consists of the following information:.Bits per component, which is the number of bits in each individual color component in a pixel.
For an image mask, this value is the number of significant masking bits in a source pixel. For example, if the source image is an 8-bit mask, specify 8 bits per component.Bits per pixel, which is the total number of bits in a source pixel. This value must be at least the number of bits per component times the number of components per pixel.Bytes per row.
The number of bytes per horizontal row in the image.Color Spaces and Bitmap LayoutTo ensure that Quartz correctly interprets the bits of each pixel, you must specify:.Whether a bitmap contains an alpha channel. Quartz supports RGB, CMYK, and gray color spaces. It also supports alpha, or transparency, although alpha information is not available in all bitmap image formats. When it is available, the alpha component can be located in either the most significant bits of a pixel or the least significant bits.For bitmaps that have an alpha component, whether the color components are already multiplied by the alpha value. Premultiplied alpha describes a source color whose components are already multiplied by an alpha value.
Premultiplying speeds up the rendering of an image by eliminating an extra multiplication operation per color component. For example, in an RGB color space, rendering an image with premultiplied alpha eliminates three multiplication operations (red times alpha, green times alpha, and blue times alpha) for each pixel in the image.The data format of the samples—integer or floating-point values.When you create an image using the function CGImageCreate, you supply a bitmapInfo parameter, of type CGImageBitmapInfo, to specify bitmap layout information. Table 11-1 Functions for creating imagesFunctionDescriptionCGImageCreateA flexible function for creating an image. You must specify all the bitmap information that is discussed in.CGImageSourceCreateImageAtIndexCreates an image from an image source. Image sources can contain more than one image. See for information on creating an image source.CGImageSourceCreateThumbnailAtIndexCreates a thumbnail image of an image that is associated with an image source.
CGImageRef myImage;myImage = CGBitmapContextCreateImage (myBitmapContext);The CGImage object returned by the function is created by a copy operation. Therefore any subsequent changes you make to the bitmap graphics context do not affect the contents of the returned CGImage object.
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 an Image MaskA Quartz bitmap image mask is used the same way an artist uses a silkscreen. A bitmap image mask determines how color is transferred, not which colors are used. Each sample value in the image mask specifies the amount that the current fill color is masked at a specific location. The sample value specifies the opacity of the mask.
Larger values represent greater opacity and specify locations where Quartz paints less color. You can think of the sample value as an inverse alpha value. A value of 1 is transparent and 0 is opaque.Image masks are 1, 2, 4, or 8 bits per component. For a 1-bit mask, a sample value of 1 specifies sections of the mask that block the current fill color. A sample value of 0 specifies sections of the mask that show the current fill color of the graphics state when the mask is painted. You can think of a 1-bit mask as black and white; samples either completely block paint or completely allow paint.Image masks that have 2, 4, or 8 bits per component represent grayscale values. Each component maps to a range of 0 to 1 using the following formula:For example, a 4-bit mask has values that range from 0 to 1 in increments of 1/15.
Component values that are 0 or 1 represent the extremes—completely block paint and completely allow paint. Values between 0 and 1 allow partial painting using the formula 1 – MaskSampleValue. For example, if the sample value of an 8-bit mask scales to 0.7, color is painted as if it had an alpha value of (1 – 0.7), which is 0.3.The function CGImageMaskCreate creates a Quartz image mask from bitmap image information that you supply and that is discussed in. The information you supply to create an image mask is the same as what you supply to create an image, except that you do not supply color space information, a bitmap information constant, or a rendering intent, as you can see by looking at the function prototype in Listing 11-2.Listing 11-2 The prototype for the function CGImageMaskCreate.
CGContextSetBlendMode (myContext, kCGBlendModeDarken);CGContextDrawImage (myContext, myRect, myImage2);The rest of this section uses each of the blend modes available in Quartz to draw the image shown on the right side of Figure 11-17 over the background that consists of the painted rectangles shown on the left side of the figure. In all cases, the rectangles are first drawn to the graphics context. Then, a blend mode is set by calling the function CGContextSetBlendMode, passing the appropriate blend mode constant.
Finally, the image of the jumper is drawn to the graphics context. Figure 11-17 Background drawing (left) and foreground image (right) Normal Blend ModeNormal blend mode paints source image samples over background image samples. Normal blend mode is the default blend mode in Quartz. You only need to explicitly set normal blend mode if you are currently using another blend mode and want to switch to normal blend mode. You can set normal blend mode by passing the constant kCGBlendModeNormal to the function CGContextSetBlendMode or by restoring the graphics state (assuming the previous graphics state used normal blend mode) using the function CGContextRestoreGState.Figure 11-18 shows the result of using normal blend mode to paint the image shown in over the rectangles shown in the same figure. In this example, the image is drawn using an alpha value of 1.0, so the background is completely obscured by the image.
Figure 11-18 Drawing an image over a background using normal blend mode Multiply Blend ModeMultiply blend mode multiplies source image samples with background image samples. The colors in the resulting image are at least as dark as either of the two contributing sample colors.You specify multiply blend mode by passing the constant kCGBlendModeMultiply to the function CGContextSetBlendMode. Figure 11-19 shows the result of using multiply blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-19 Drawing an image over a background using multiply blend mode Screen Blend ModeScreen blend mode multiplies the inverse of the source image samples with the inverse of the background image samples to obtain colors that are at least as light as either of the two contributing sample colors.You specify screen blend mode by passing the constant kCGBlendModeScreen to the function CGContextSetBlendMode. Figure 11-20 shows the result of using screen blend mode to paint the image shown in over the rectangles shown in the same figure.
Figure 11-20 Drawing an image over a background using screen blend mode Overlay Blend ModeOverlay blend mode either multiplies or screens the source image samples with the background image samples, depending on the color of the background samples. The result is to overlay the existing image samples while preserving the highlights and shadows of the background. The background color mixes with the source image to reflect the lightness or darkness of the background.You specify overlay blend mode by passing the constant kCGBlendModeOverlay to the function CGContextSetBlendMode. Figure 11-21 shows the result of using overlay blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-21 Drawing an image over a background using overlay blend mode Darken Blend ModeDarken blend mode creates composite image samples by choosing the darker samples from the source image or the background. Source image samples that are darker than the background image samples replace the corresponding background samples.You specify darken blend mode by passing the constant kCGBlendModeDarken to the function CGContextSetBlendMode.
Figure 11-22 shows the result of using darken blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-22 Drawing an image over a background using darken blend mode Lighten Blend ModeLighten blend mode creates composite image samples by choosing the lighter samples from the source image or the background. Source image samples that are lighter than the background image samples replace the corresponding background samples.You specify lighten blend mode by passing the constant kCGBlendModeLighten to the function CGContextSetBlendMode. Figure 11-23 shows the result of using lighten blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-23 Drawing an image over a background using lighten blend mode Color Dodge Blend ModeColor dodge blend mode brightens background image samples to reflect the source image samples. Source image sample values that specify black remain unchanged.You specify color dodge blend mode by passing the constant kCGBlendModeColorDodge to the function CGContextSetBlendMode. Figure 11-24 shows the result of using color dodge blend mode to paint the image shown in over the rectangles shown in the same figure.
Figure 11-24 Drawing an image over a background using color dodge blend mode Color Burn Blend ModeColor burn blend mode darkens background image samples to reflect the source image samples. Source image sample values that specify white remain unchanged.You specify color burn blend mode by passing the constant kCGBlendModeColorBurn to the function CGContextSetBlendMode. Figure 11-25 shows the result of using color burn blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-25 Drawing an image over a background using color burn blend mode Soft Light Blend ModeSoft light blend mode either darkens or lightens colors, depending on the source image sample color. If the source image sample color is lighter than 50% gray, the background lightens, similar to dodging. If the source image sample color is darker than 50% gray, the background darkens, similar to burning. If the source image sample color is equal to 50% gray, the background does not change.Image samples that are equal to pure black or pure white produce darker or lighter areas, but do not result in pure black or white.
The overall effect is similar to what you achieve by shining a diffuse spotlight on the source image.You specify soft light blend mode by passing the constant kCGBlendModeSoftLight to the function CGContextSetBlendMode. Figure 11-26 shows the result of using soft light blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-26 Drawing an image over a background using soft light blend mode Hard Light Blend ModeHard light blend mode either multiplies or screens colors, depending on the source image sample color. If the source image sample color is lighter than 50% gray, the background is lightened, similar to screening. If the source image sample color is darker than 50% gray, the background is darkened, similar to multiplying. If the source image sample color is equal to 50% gray, the source image does not change. Image samples that are equal to pure black or pure white result in pure black or white.
The overall effect is similar to what you achieve by shining a harsh spotlight on the source image.You specify hard light blend mode by passing the constant kCGBlendModeHardLight to the function CGContextSetBlendMode. Figure 11-27 shows the result of using hard light blend mode to paint the image shown in over the rectangles shown in the same figure.
Figure 11-27 Drawing an image over a background using hard light blend mode Difference Blend ModeDifference blend mode subtracts either the source image sample color from the background image sample color, or the reverse, depending on which sample has the greater brightness value. Source image sample values that are black produce no change; white inverts the background color values.You specify difference blend mode by passing the constant kCGBlendModeDifference to the function CGContextSetBlendMode. Figure 11-28 shows the result of using difference blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-28 Drawing an image over a background using difference blend mode Exclusion Blend ModeExclusion blend mode produces a lower-contrast version of the difference blend mode.
Source image sample values that are black don’t produce a change; white inverts the background color values.You specify exclusion blend mode by passing the constant kCGBlendModeExclusion to the function CGContextSetBlendMode. Figure 11-29 shows the result of using exclusion blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-29 Drawing an image over a background using exclusion blend mode Hue Blend ModeHue blend mode uses the luminance and saturation values of the background with the hue of the source image. You specify hue blend mode by passing the constant kCGBlendModeHue to the function CGContextSetBlendMode. Figure 11-30 shows the result of using hue blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-30 Drawing an image over a background using hue blend mode Saturation Blend ModeSaturation blend mode uses the luminance and hue values of the background with the saturation of the source image.
Pure gray areas don’t produce a change. You specify saturation blend mode by passing the constant kCGBlendModeSaturation to the function CGContextSetBlendMode. Figure 11-31 shows the result of using saturation blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-31 Drawing an image over a background using saturation blend mode Color Blend ModeColor blend mode uses the luminance values of the background with the hue and saturation values of the source image. This mode preserves the gray levels in the image. You specify color blend mode by passing the constant kCGBlendModeColor to the function CGContextSetBlendMode. Figure 11-32 shows the result of using color blend mode to paint the image shown in over the rectangles shown in the same figure.
Figure 11-32 Drawing an image over a background using color blend mode Luminosity Blend ModeLuminosity blend mode uses the hue and saturation of the background with the luminance of the source image to create an effect that is inverse to the effect created by the color blend mode.You specify luminosity blend mode by passing the constant kCGBlendModeLuminosity to the function CGContextSetBlendMode. Figure 11-33 shows the result of using luminosity blend mode to paint the image shown in over the rectangles shown in the same figure. Figure 11-33 Drawing an image over a background using luminosity blend mode.
![]() Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. Archives
January 2023
Categories |