Graphic context explanation of Quartz-2D drawing, quartz-2d Context

Source: Internet
Author: User

Graphic context explanation of Quartz-2D drawing, quartz-2d Context

The previous article roughly described the things in Quartz, but did not talk about the specific implementation details and how to call the corresponding API. This article describes the specific operations of the graphic Context.

The so-called Graphics Context represents a drawing target, that is, the place where you plan to draw. It contains the drawing parameters and device information used by the drawing system to complete the drawing command. Graphics Context defines basic drawing attributes, such as color, cut area, line width and style information, font information, and mixed mode. However, how can we obtain or create a Graphics Context? There are naturally many methods: the functions provided by Quartz, the Mac OS X framework, or the functions provided by the IOS UIKit framework. Quartz provides a variety of Graphics Context creation functions, including bitmap and PDF. We can use these Graphics Context to create custom content. Next we will introduce how to create Graphics Context for different drawing targets. In the code, CGContextRef is used to represent a Graphics Context. After obtaining a Graphics Context, you can use the Quartz 2D function to draw and complete operations (such as translation) in the context, and modify Graphics status parameters (such as linewidth and fill color.

I,Draw the Graphics Context of UIView in iOS

In iOS apps, if you want to draw on the screen, you need to create a UIView object and implement its drawRect: method. View drawRect: The method is called when the view is displayed on the screen and its content needs to be updated. After the custom drawRect: is called, the view object automatically configures the drawing environment so that the code can immediately perform the Drawing operation. As part of the configuration, the view object creates a Graphics Context for the current drawing environment. We can call the UIGraphicsGetCurrentContext function to obtain the Graphics Context.

For example, draw a circle in UIView.

1-(void) drawRect :( CGRect) rect {2 3 // 1. obtain the context associated with the view. 4 CGContextRef context = UIGraphicsGetCurrentContext (); 5 6 // set the color. 7 [[UIColor greenColor] setFill]; 8 9 // 2. add the circular path 10 CGContextAddEllipseInRect (context, CGRectMake (50, 50,200,200); 11 // 3. circle 12 CGContextFillPath (context); 13 14}

PS: the default Coordinate System of UIKit is different from that of Quartz. In UIKit, the origin is in the upper left corner, and the positive direction of the Y axis is downward. UIView matches UIView by translating the CTM of Graphics Context of Quartz to the lower left corner and reversing the y axis (y value multiplied by-1. These are all completed automatically by the system.

II,Create a PDF Graphics Context

The Quartz 2D API provides two functions to create a PDF Graphics Context: When a PDF Graphics Context is created and drawn, Quartz records the painting operation as a series of PDF drawing commands and writes them into the file. We need to provide a PDF output location and a default media box (used to specify the rectangle of the page boundary ).

1. cgw.contextcreatewithurl: this function is used when you need to use the Core Foundation URL to specify the position of the pdf output.

 1 CGContextRef MyPDFContextCreate (const CGRect *inMediaBox, CFStringRef path) 2 { 3     CGContextRef myOutContext = NULL; 4     CFURLRef url; 5     url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, false); 6     if (url != NULL) { 7         myOutContext = CGPDFContextCreateWithURL (url,  inMediaBox,  NULL); 8         CFRelease(url); 9     }10     return myOutContext;11 }

2. cgw.contextcreate: This method is used to send pdf output to data users.

 1 CGContextRef MyPDFContextCreate (const CGRect *inMediaBox, CFStringRef path) 2 { 3     CGContextRef        myOutContext = NULL; 4     CFURLRef            url; 5     CGDataConsumerRef   dataConsumer; 6     url = CFURLCreateWithFileSystemPath (NULL,  path, kCFURLPOSIXPathStyle, false); 7     if (url != NULL) 8     { 9         dataConsumer = CGDataConsumerCreateWithURL (url);10         if (dataConsumer != NULL)11         {12             myOutContext = CGPDFContextCreate (dataConsumer, inMediaBox, NULL);13             CGDataConsumerRelease (dataConsumer);14         }15         CFRelease(url);16     }17     return myOutContext;18 } 

The following describes how to call the my‑contextcreate program and draw a project.

1 CGRect mediaBox; 2 mediaBox = CGRectMake (0, 0, myPageWidth, myPageHeight); 3 mydomaincontext = mydomaincontextcreate (& mediaBox, CFSTR ("testbench ")); 4 CFStringRef myKeys [1]; 5 CFTypeRef myValues [1]; 6 myKeys [0] = values; 7 myValues [0] = (CFTypeRef) CFDataCreate (NULL, (const UInt8 *) & mediaBox, sizeof (CGRect); 8 CFDictionaryRef pageDictionary = CFDictionaryCreate (NULL, (const void **) myKeys, 9 (const void **) myValues, 1, 10 & found, 11 & kCFTypeDictionaryValueCallBacks); 12 cg1_contextbeginpage (mydomaincontext, & pageDictionary ); 13 // ********************* 14 CGContextSetRGBFillColor (mydomaincontext, 1, 0, 0, 1 ); 15 CGContextFillRect (my‑context, CGRectMake (0, 0,200,100); 16 CGContextSetRGBFillColor (my‑context, 0, 0, 1 ,. 5); 17 CGContextFillRect (my‑context, CGRectMake (0, 0,100,200); 18 cg‑contextendpage (my‑context); 19 CFRelease (pageDictionary); 20 CFRelease (myValues [0]); 21 CGContextRelease (mydomaincontext );

We can draw any content (images, text, and paths) to pdf, and add links and encryption.

Add Link
We can add links and anchor points in the PDF context. Quartz provides three functions, each of which takes the PDF image context as the parameter and has link information:
· Cgw.contextseturlforrect allows us to open a URL when clicking the rectangle in the current PDF page.
· Cgw.contextsetdestinationforrect specifies to set the target when you click the rectangle area on the current PDF page to jump. We need to provide a target name.
· Cgw.contextadddestinationatpoint specifies to set the target when you click a point on the current PDF page to jump. We need to provide a target name.
Protect PDF content
To protect PDF content, you can specify some security options in the secondary dictionary and pass them to cgw.contextcreate. You can set whether the owner password, user password, and PDF file can be printed or copied by using the following keywords:
· Kcgw.contextownerpassword: defines the owner password of the PDF document. If this value is specified, the document is encrypted using the owner password; otherwise, the document is not encrypted. The value of this keyword must be an ASCII CFString object. Only the first 32 bits are used for passwords. This value has no default value. If the value cannot be expressed as ASCII, the document cannot be created and NULL is returned. Quartz uses 40-bit encryption.
· Kcg1_contextuserpassword: defines the user password of the PDF document. If the document is encrypted, the value is the document's user password. If not specified, the user password is blank. The value of this keyword must be an ASCII CFString object. Only the first 32 bits are used for passwords. If the value cannot be expressed as ASCII, the document cannot be created and NULL is returned.
· Kcg?contextallowsprinting: Specifies whether the document can be printed when the user password lock is used. The value must be a CFBoolean object. The default value is kCGBooleanTrue.
· Kcg?contextallowscopying: Specifies whether the document can be copied when the user password lock is used. The value must be a CFBoolean object. The default value is kCGBooleanTrue.
Code list 14-4 (next chapter) shows how to check whether the PDF document is locked and use a password to open the document.

Of course, in iOS, we can completely pass through these obscure underlying code, because the system provides us with a higher level of functions to generate PDF files. below is the code

1-(void) createPDFFile 2 {3 // 1. CONTEXT 4 // 1) Path 5 // 2) size. If it is null, 612*792 is used as the page size of the PDF file 6 // 3) dict 7 uigraphicsbegin1_contexttofile (@ "/Users/apple/Desktop/demofile", CGRectZero, nil); 8 9 // 2. write content 10 // There is a page in the pdf, a page is written to a page 11 // create a PDF page 12 // a page can write up to two images, therefore, writing 6 images requires three pages 13 for (NSInteger I = 0; I <6; I ++) {14 if (I % 2 = 0) {15 tests (CGRectMake (0, 0,612,792), nil); 16} 17 18 // generate UIImage19 UIImage * image = [UIImage imageNamed: [NSString stringWithFormat: @ "natgeo=02d.png ", I + 1]; 20 // write 21 [image drawAtPoint: CGPointMake (0,400 * (I % 2)]; 22} 23 24 // 3. disable the context 25 uigraphicsendinclucontext (); 26}

III,Create a bitmap Graphics Context

A bitmap Graphics Context receives a pointer to the memory cache (including the bitmap bucket). When we draw a bitmap Graphics Context, the cache is updated. After Graphics Context is released, a new bitmap in the specified pixel format is obtained.

We use CGBitmapContextCreate to create the bitmap Graphics Context. This function has the following parameters:

  • Data: a pointer to the memory target, which is used to store the graphic data to be rendered. The size of the memory block must be at least bytePerRow * height.
  • Width: Specify the width of the bitmap, in pixels ).
  • Height: Specify the height of the bitmap, in pixels ).
  • BitsPerComponent: specifies the number of digits used by each component in one pixel of memory. For example, for a 32-bit pixel format and an rgb color space, we can specify each component as eight bits.
  • BytesPerRow: specifies the number of bytes in each row of the bitmap.
  • Colorspace: color space is used for bitmap context. When creating a bitmap Graphics Context, we can use gray, RGB, CMYK, and NULL color spaces.
  • BitmapInfo: bitmap information, which is used to specify whether the bitmap needs to contain the alpha component, the relative position (if any) of the alpha component in the pixel, and whether the alpha component is premultiplied, and whether the color component is an integer or floating point value.

The following code creates a bitmap Graphics Context. When drawing to the bitmap Graphics Context, Quartz records the drawing to the block specified in the memory.

 

 1 CGContextRef MyCreateBitmapContext (int pixelsWide, int pixelsHigh) 2 { 3     CGContextRef    context = NULL; 4     CGColorSpaceRef colorSpace; 5     void *          bitmapData; 6     int             bitmapByteCount; 7     int             bitmapBytesPerRow; 8     bitmapBytesPerRow   = (pixelsWide * 4); 9     bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);10     colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);11     bitmapData = calloc( bitmapByteCount );12     if (bitmapData == NULL)13     {14         fprintf (stderr, "Memory not allocated!");15         return NULL;16     }17     context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);18     if (context== NULL)19     {20         free (bitmapData);21         fprintf (stderr, "Context not created!");22         return NULL;23     }24     CGColorSpaceRelease( colorSpace );25     return context;26 }

 

Next, call MyCreateBitmapContext to create a bitmap Graphics Context, use the bitmap Graphics Context to create a CGImage object, and then draw the image to the window Graphics Context.

 1 CGRect myBoundingBox; 2     myBoundingBox = CGRectMake (0, 0, myWidth, myHeight); 3     myBitmapContext = MyCreateBitmapContext (400, 300); 4     // ********** Your drawing code here **********  5     CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1); 6     CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 )); 7     CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5); 8     CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 )); 9     myImage = CGBitmapContextCreateImage (myBitmapContext);10     CGContextDrawImage(myContext, myBoundingBox, myImage);11     char *bitmapData = CGBitmapContextGetData(myBitmapContext); 12     CGContextRelease (myBitmapContext);13     if (bitmapData) free(bitmapData); 14     CGImageRelease(myImage);

The above is the underlying code of Quartz. Then, in actual iOS development, the iOS application uses uigraphicsbeginimagecontextwitexceptions to replace the lower-layer functions of Quartz. So if you are only engaged in iOS development, the obscure code above can be completely passed. If you use Quartz to create a background bitmap, the coordinate system used by bitmap Graphics Context is the default Coordinate System of Quartz. When uigraphicsbeginimagecontextwitexceptions is used to create a graphic context, UIKit will convert the coordinate system using the same image context as the UIView object. This allows applications to use the same drawing code without worrying about coordinate system issues. Although our application can manually adjust the CTM to achieve the same effect, this does not have any advantages.

The following code uses uigraphicsbeginimagecontextwitexceptions in iOS to crop a circular bitmap and return it.

+ (Instancetype) circleImageWithName :( NSString *) name borderWidth :( CGFloat) borderWidth borderColor :( UIColor *) borderColor {// 1. load the source image UIImage * oldImage = [UIImage imageNamed: name]; // 2. enable the context CGFloat imageW = oldImage. size. width + 2 * borderWidth; CGFloat imageH = oldImage. size. height + 2 * borderWidth; CGSize imageSize = CGSizeMake (imageW, imageH); uigraphicsbeginimagecontextwitexceptions (imageSize, NO, 0.0); // 3. obtain the current context CGContextRef ctx = UIGraphicsGetCurrentContext (); // 4. border (large circle) [borderColor set]; CGFloat bigRadius = imageW * 0.5; // large circle radius CGFloat centerX = bigRadius; // center CGFloat centerY = bigRadius; CGContextAddArc (ctx, centerX, centerY, bigRadius, 0, M_PI * 2, 0); CGContextFillPath (ctx); // circle // 5. small Round CGFloat smallRadius = bigRadius-borderWidth; CGContextAddArc (ctx, centerX, centerY, smallRadius, 0, M_PI * 2, 0 ); // crop (the things drawn after the cropping will be affected) CGContextClip (ctx); // 6. drawing [oldImage drawInRect: CGRectMake (borderWidth, borderWidth, oldImage. size. width, oldImage. size. height)]; // 7. figure UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext (); // 8. end context UIGraphicsEndImageContext (); return newImage ;}

Supported pixel formats

Table 2-1 summarizes the pixel formats supported by the bitmap Graphics Context, the color space, and the oldest Mac OS X versions supported by the pixel format. The pixel format is represented by bpp (the number of digits per pixel) and bpc (the number of digits per component. The table also contains bitmap information constants related to the pixel format.

Table 2-1: pixel formats supported by the bitmap Graphics Context

 

Null 8 bpp, 8 bpc, kCGImageAlphaOnly Mac OS X, iOS
Gray 8 bpp, 8 bpc, kCGImageAlphaNone Mac OS X, iOS
Gray 8 bpp, 8 bpc, kCGImageAlphaOnly Mac OS X, iOS
Gray 16 bpp, 16 bpc, kCGImageAlphaNone Mac OS X
Gray 32 bpp, 32 bpc, kCGImageAlphaNone | kCGBitmapFloatComponents Mac OS X
RGB 16 bpp, 5 bpc, kCGImageAlphaNoneSkipFirst Mac OS X, iOS
RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipFirst Mac OS X, iOS
RGB 32 bpp, 8 bpc, kCGImageAlphaNoneSkipLast Mac OS X, iOS
RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedFirst Mac OS X, iOS
RGB 32 bpp, 8 bpc, kCGImageAlphaPremultipliedLast Mac OS X, iOS
RGB 64 bpp, 16 bpc, kCGImageAlphaPremultipliedLast Mac OS X
RGB 64 bpp, 16 bpc, kCGImageAlphaNoneSkipLast Mac OS X
RGB 128 bpp, 32 bpc, kCGImageAlphaNoneSkipLast | kCGBitmapFloatComponents Mac OS X
RGB 128 bpp, 32 bpc, kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents Mac OS X
CMYK 32 bpp, 8 bpc, kCGImageAlphaNone Mac OS X
CMYK 64 bpp, 16 bpc, kCGImageAlphaNone Mac OS X
CMYK 128 bpp, 32 bpc, kCGImageAlphaNone | kCGBitmapFloatComponents Mac OS X

Anti-sawtooth
The bitmap Graphics Context supports anti-sawtooth. This operation is a jagged edge generated when a text or shape is drawn in a positive image. When the bitmap resolution is significantly lower than the resolution of the human eye, it will produce sawtooth. In order to make the objects in the bitmap look smooth, Quartz uses different colors to fill the pixels around the shape. In this way, colors are mixed to make the shape look smoother. 2-4. You can call CGContextSetShouldAntialias to disable the anti-sawtooth effect of the bitmap Graphics Context. The anti-sawtooth setting is part of the graph status.
You can call the CGContextSetAllowsAntialiasing function to control whether a specific Graphics Context supports anti-aliasing. false indicates not. This setting is not part of the graph status. When the context and image status are set to true, Quartz performs anti-aliasing, as shown in figure

 

IV,Obtain the printed Graphics Context
The Cocoa application in Mac OS X is printed using the custom NSView subclass. A view is printed by calling the print method. The view then creates a Graphics Context with the printer as the target and calls the drawRect: method. The application uses the same drawing code as drawing on the screen. We can also customize the drawRect: Method to draw graphics to the printer.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.