1. quartz2d Overview and role
The quartz2d API is pure C, and the Quartz2d API comes from the core graphics framework.
Data types and functions are basically prefixed with CG, such as:
Cgcontextref
Cgpathref
Cgcontextstrokepath (CTX);
......
The Quartz 2D is a two-dimensional drawing engine that supports both iOS and Mac systems.
Quartz 2D work that can be done:
Drawing: line \ triangle \ rectangle \ Circle \ arc, etc.;
Draw text;
Draw \ Generate picture (image);
Read \ generate PDF;
\ crop the picture;
Custom UI controls;
... ...
2 , quartz2d in the IOS value in development
To facilitate an aesthetically pleasing UI, iOS provides a uikit framework with a variety of UI controls, such as:
UILabel: Display text;
Uiimageview: Display picture;
UIButton: Simultaneous display of pictures and text (can be clicked);
... ...
Using the controls provided by the Uikit framework, you can build and create some simple, common UI interfaces.
However, some UI interfaces are extremely complex and more personalized and cannot be implemented with normal UI controls, so you can use quartz2d technology to draw the structure inside the control and customize what the control looks like. In fact, the content of most controls in iOS is drawn through quartz2d. As a result,quartz2d is an important value in IOS Development: Custom View(custom UI Control).
3 , Graphics context
Graphics context: is a cgcontextref type of data.
The role of the graphics context:
(1) Save drawing information, drawing status
(2) Decide which output target to draw (where to go?) )
(The output target can be a PDF file, a bitmap or a display window)
The same set of drawing sequences, specifying different graphics Context, can draw the same image to different targets.
quartz2d provides the following types of Graphics Context :
(1) Bitmap Graphics Context
(2) PDF Graphics Context
(3) Window Graphics Context
(4) Layer Graphics Context
(5) Printer Graphics Context
4 , Custom View
How do I customize view with quartz2d? (Custom UI control) How can I draw things to the view using quartz2d?
First, you have to have a graphical context, because it saves the drawing information and determines where to draw it.
Second, the graphics context must be associated with the view to draw the content onto the view.
Custom View the steps:
(1) Create a new class that inherits from UIView
(2) Implement-(void) DrawRect: (CGRect) Rect method, and then in this method
(a) Obtain a graphical context associated with the current view
For example: Cgcontextref CTX = Uigraphicsgetcurrentcontext ();
(a) drawing the corresponding graphic content
For example: Draw 1/4 Circles
Cgcontextmovetopoint (CTX, 100, 100);
Cgcontextaddlinetopoint (CTX, 100, 150);
Cgcontextaddarc (CTX,-m_pi_2, M_PI, 1);
Cgcontextclosepath (CTX);
[[Uicolor Redcolor] set];
(b) Render all rendered content to the view using a graphical context
For example: Cgcontextfillpath (CTX);
5 , DrawRect
Why implement DrawRect: How can I draw to a view?
Because the graphics context associated with the view can be obtained in the drawrect: method.
DrawRect: When is the method called?
(1) When the view is displayed on the screen for the first time (it is added to the UIWindow).
(2) Call the view's Setneedsdisplay or Setneedsdisplayinrect: When.
Setneedsdisplay is often called to refresh View interface.
Drawing order:
3. DrawRect: The context that is obtained in
After you get the context in the DrawRect: method, you can draw something to the view. There is a layer property inside the view, DrawRect: The method obtains a layer Graphics Context, so the drawing is actually drawn to the view layer. View is able to show things entirely because of its inner layer.
4. quartz2d code steps for drawing
First step: Get the graphical context:
Cgcontextref CTX = Uigraphicsgetcurrentcontext ();
Step two: Stitching the path (the following code is a line segment):
Cgcontextmovetopoint (CTX, 10, 10);
Cgcontextaddlinetopoint (CTX, 100, 100);
Step three: Draw the path:
Cgcontextstrokepath (CTX); Cgcontextfillpath (CTX);
7 , common stitching path function
- Create a new starting point
void Cgcontextmovetopoint (Cgcontextref C, CGFloat x, cgfloat y)
- Add a new segment to a point
void Cgcontextaddlinetopoint (Cgcontextref C, CGFloat x, cgfloat y)
void Cgcontextaddrect (Cgcontextref C, CGRect rect)
void Cgcontextaddellipseinrect (Cgcontextref context, CGRect rect)
void Cgcontextaddarc (Cgcontextref C, CGFloat x, CGFloat y,
CGFloat radius, cgfloat startangle, cgfloat endangle, int clockwise)
8 , common drawing path functions
- Mode parameter determines the pattern to be drawn
void Cgcontextdrawpath (cgcontextref C, Cgpathdrawingmode mode)
void Cgcontextstrokepath (Cgcontextref c)
void Cgcontextfillpath (Cgcontextref c)
Tip: Functions that are usually started with Cgcontextdraw, Cgcontextstroke, and Cgcontextfill are used to draw the path
Other common functions:
To set the segment width:
Cgcontextsetlinewidth (CTX, 10);
Set the style for the end of the segment head:
Cgcontextsetlinecap (CTX, Kcglinecapround);
To set the style of the segment inflection point:
Cgcontextsetlinejoin (CTX, Kcglinejoinround);
To set the color:
Cgcontextsetrgbstrokecolor (CTX, 1, 0, 0, 1);
9 , the operation of the graphics context stack
Save the current context copy to the top of the stack (the stack is called the "graphics Context stack"):
void Cgcontextsavegstate (Cgcontextref c)
Stack the context of the top of the stack, replacing the current context (before emptying for context settings):
void Cgcontextrestoregstate (Cgcontextref c)
Ten , matrix manipulation
With a matrix operation, all paths drawn to the context can be changed together:
Scaling:
void Cgcontextscalectm (Cgcontextref C, cgfloat SX, CGFloat Sy)
Rotating:
void Cgcontextrotatectm (cgcontextref C, cgfloat angle)
Translation:
void Cgcontexttranslatectm (Cgcontextref c, CGFloat tx, cgfloat ty)
One , quartz2d the memory management
With regard to memory management, there are the following principles:
(1) An object created with a function containing "create" or "Copy" must be released after use, or a memory leak will result.
(2) An object obtained using a function that does not contain "Create" or "Copy" does not need to be freed
(3) If an object is retain, it needs to be removed when it is no longer in use.
(4) You can use the Quartz 2D function to specify retain and release an object. For example, if you create a Cgcolorspace object, use the functions Cgcolorspaceretain and cgcolorspacerelease to retain and release the object.
(5) You can also use the Cfretain and cfrelease of the core Foundation. Note You cannot pass null values to these functions.
11. Image Watermark
Sometimes, in the mobile phone client app also need to use the watermark technology, for example, the user after taking a photo, you can make a watermark in the photo, identify the image belongs to which user
Implementation method:
Use quartz2d to draw the watermark (text, LOGO) to the lower right corner of the picture
Core code:
To open a bitmap-based graphics context:
void Uigraphicsbeginimagecontextwithoptions (cgsize size, BOOL opaque, cgfloat scale)
Get the picture from the context (UIImage):
uiimage* Uigraphicsgetimagefromcurrentimagecontext ();
To end a bitmap-based graphics context:
void Uigraphicsendimagecontext ();
For example:
UIImage *bgimage = [UIImage imagenamed:@ "scene"];
Context: Bitmap-based (bitmap), all things need to be drawn to a new picture up
1. Create a bitmap-based context (open a bitmap-based context)
Size: The dimensions of the new picture
Opaque:yes: Opaque, no: transparent
This line of code is followed by a common new bitmap, the new UIImage object.
Uigraphicsbeginimagecontextwithoptions (Bgimage.size, NO, 0.0);
2. Painting background
// special attention is paid to the use OC the system automatically detects and passes in the context when it is not in the context of its own drawing method
[Bgimage drawinrect:cgrectmake (0, 0, BgImage.size.width, bgImage.size.height)];
3. Draw the watermark in the lower right corner
UIImage *waterimage = [UIImage imagenamed:@ "logo"];
CGFloat scale = 0.2;
CGFloat margin = 5;
CGFloat WATERW = waterImage.size.width * scale;
CGFloat waterh = waterImage.size.height * scale;
CGFloat Waterx = Bgimage.size.width-waterw-margin;
CGFloat watery = bgimage.size.height-waterh-margin;
[Waterimage Drawinrect:cgrectmake (Waterx, watery, waterw, Waterh)];
4. Get the finished UIImage object from the context
UIImage *newimage =
Uigraphicsgetimagefromcurrentimagecontext ();
5. End Context
Uigraphicsendimagecontext ();
6. Show to Uiimageview
Self.iconView.image = NewImage;
7. Compressing the image object to binary data in PNG format
NSData *data = uiimagepngrepresentation (newimage);
UIImageJPEGRepresentation (< #UIImage *image#>, < #CGFloat compressionquality#>)
8. Writing files
NSString *path =
[[Nssearchpathfordirectoriesindomains (NSDocumentDirectory, Nsuserdomainmask, YES) Lastobject]
stringByAppendingPathComponent: @ "New.png"];
[Data Writetofile:path Atomically:yes];
- , picture clipping
Sometimes we need to cut a normal picture into a circle, such as a circle of the user's head, such as:
Core code:
void Cgcontextclip (Cgcontextref c)
Crop the path that is currently drawn up or down (it cannot be displayed beyond the clipping area)
Sample Code 1 (effects such as):
Cgcontextref CTX = Uigraphicsgetcurrentcontext ();
Draw a Circle
Cgcontextaddellipseinrect (CTX, CGRectMake (100, 100, 50, 50));
Cutting
Cgcontextclip (CTX);
Cgcontextfillpath (CTX);
Show pictures
UIImage *image = [UIImage imagenamed:@ "Me"];
[Image Drawatpoint:cgpointmake (100, 100)];
Sample Code 2 (produces an image circle with the same effect as the picture above but adds a rounded border around the image and saves it locally):
1. Loading the original
UIImage *oldimage = [UIImage imagenamed:@ "Me"];
2. Open context
CGFloat borderw = 2; Width of the ring
CGFloat Imagew = oldImage.size.width + 2 * BORDERW;
CGFloat Imageh = oldImage.size.height + 2 * BORDERW;
Cgsize imageSize = Cgsizemake (Imagew, Imageh);
Uigraphicsbeginimagecontextwithoptions (ImageSize, NO, 0.0);
3. Get the current context
Cgcontextref CTX = Uigraphicsgetcurrentcontext ();
4. Draw the border (great circle)
[[Uicolor Whitecolor] set];
CGFloat Bigradius = Imagew * 0.5; Circle radius
CGFloat CenterX = Bigradius; Center
CGFloat centery = Bigradius;
Cgcontextaddarc (CTX, CenterX, CenterY, Bigradius, 0, M_PI * 2, 0);
Cgcontextfillpath (CTX); Draw a Circle
5. Small Circle
CGFloat Smallradius = bigradius-borderw;
Cgcontextaddarc (CTX, CenterX, CenterY, Smallradius, 0, M_PI * 2, 0);
Cropping (the things that are drawn later will be affected by clipping)
Cgcontextclip (CTX);
6. Drawing
[Oldimage Drawinrect:cgrectmake (Borderw, Borderw, OldImage.size.width, OldImage.size.height)];
7. Take a picture
UIImage *newimage =
Uigraphicsgetimagefromcurrentimagecontext ();
8. End Context
Uigraphicsendimagecontext ();
9. Show pictures
Self.iconView.image = NewImage;
10. Write the file
NSData *data = uiimagepngrepresentation (newimage);
NSString *path =
[[Nssearchpathfordirectoriesindomains (NSDocumentDirectory,
Nsuserdomainmask, YES) Lastobject]
stringbyappendingpathcomponent:@ "New.png"];
[Data Writetofile:path Atomically:yes];
- , Screen
Sometimes you need to intercept a piece of content on the screen, such as a fishing talent game:
Core code:
-(void) Renderincontext: (cgcontextref) CTX;
Call the Renderincontext of a view's layer: method to
Example code:
1. Open context
Uigraphicsbeginimagecontextwithoptions (View.frame.size, NO, 0.0);
2. Render the layer of the Controller view to the context
[View.layer Renderincontext:uigraphicsgetcurrentcontext ()];
3. Remove the image
UIImage *newimage =
Uigraphicsgetimagefromcurrentimagecontext ();
4. Writing files
NSData *data = uiimagepngrepresentation (newimage);
NSString *path =
[[Nssearchpathfordirectoriesindomains (NSDocumentDirectory,
Nsuserdomainmask, YES) Lastobject]
stringbyappendingpathcomponent:@ "New.png"];
[Data Writetofile:path Atomically:yes];
5. End Context
Uigraphicsendimagecontext ();
the , OC in-band drawing method
1. Get the current touch point
Uitouch *touch = [touches anyobject];
Cgpoint startpos = [Touch LocationInView:touch.view];
2. Create a new path
Uibezierpath *currenpath = [Uibezierpath bezierpath];//can also be created using the Alloc init method
Currenpath.linecapstyle = Kcglinecapround;
Currenpath.linejoinstyle = Kcglinejoinround;
3. Setting the starting point
[Currenpath Movetopoint:startpos];
4. Connection
[Currentpath Addlinetopoint:endpos];
Determine if a point is in a rectangular box:
Cgrectcontainspoint (rect,point);//Determine if point is within rect rectangle
iOS Development quartz2d