IOS Development --- drawing

Source: Internet
Author: User

IOS Development --- drawing
Drawing operations

In iOS development, the system has provided us with powerful controls, but many of them cannot meet our needs. At this time, we need to customize some beautiful controls. The knowledge used is the drawing below.

1. Basic Drawing knowledge 1.1 graphic Context

1.1 Graphics Context: A CGContextRef type data

1.2 role of image Context
Save drawing information and drawing status
Determine the output target (where to draw ?)
(The output target can be a PDF file, Bitmap, or display window)

1.2-(void) drawRect :( CGRect) rect function: used to draw what call: when the control is displayed for the first time rect: the current control's bounds1.2 drawing steps

1. Obtain the image context:

CGContextRef ctx = UIGraphicsGetCurrentContext();

2. Splicing path

Create a start point
void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)

Add a new line segment to a point
void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)

Add a rectangle
void CGContextAddRect(CGContextRef c, CGRect rect)

Add an elliptic
void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)

Add an arc

void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,
CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)

3. Add the path to the context

The Mode parameter determines the draw Mode.
Void CGContextDrawPath (CGContextRef c, CGPathDrawingMode mode)

Draw a hollow path
Void CGContextStrokePath (CGContextRef c)

Draw solid path
Void CGContextFillPath (CGContextRef c)

Tip: Generally, functions starting with CGContextDraw, CGContextStroke, and CGContextFill are used to draw paths.

4. rendering to View

1.3 Basic Drawing example

1. draw lines

Obtain the image context: UIGraphicsGetCurrentContext()Splicing path: UIBezierPathAdd path to context CGContextAddPath(ctx, path.CGPath)Rendering to View CGContextStrokePath(ctx)
-(Void) drawLine {// a path object, which can correspond to multiple heel lines // 1. obtain the context associated with the current view. The system automatically creates the context CGContextRef ctx = UIGraphicsGetCurrentContext (); // sets the context status, you should be able to create the corresponding color object before rendering, and call the set method [[UIColor redColor] set]; // set the context width CGContextSetLineWidth (ctx, 15 ); // set the connection style CGContextSetLineJoin (ctx, kCGLineJoinRound) of a line segment; // set the endpoint style CGContextSetLineCap (ctx, kCGLineCapRound) of a line segment; // 2. splicing path, UIBezierPath, encapsulates a set of well-used paths UIBezierPath * path = [UIBezierPath bezierPath]; // 2.1 sets the starting point [path moveToPoint: CGPointMake (10,125)]; // 2.2 add a line to a certain point [path addLineToPoint: CGPointMake (220,125)]; // if only one path is used, by default, the start point of the next line is at the end point of the last line. [path addLineToPoint: CGPointMake (200,150)]; // 3. add the path to the context CGContextAddPath (ctx, path. CGPath); // 4. layer CGContextStrokePath (ctx) rendered to the view );}

2. Draw a curve

Generally, the plot is drawn using the besell curve:UIBezierPath

-(Void) drawLIneQuadCurve {// 1. obtain the context CGContextRef ctx = UIGraphicsGetCurrentContext (); // 2. splicing path UIBezierPath * path = [UIBezierPath bezierPath]; [path moveToPoint: CGPointMake (10,125)]; [path addQuadCurveToPoint: CGPointMake (240,125) controlPoint: CGPointMake (125, 0)]; // 3. path to the context CGContextAddPath (ctx, path. CGPath); // 4. rendering context // rendering in a filled manner // CGContextFillPath (ctx); CGContextStrokePath (ctx );}

3. Draw a rectangle

// Draw a rectangle-(void) drawRect {CGContextRef ctx = forward (); UIBezierPath * path = [UIBezierPath paths: CGRectMake (50, 50,100,100) cornerRadius: 50]; CGContextAddPath (ctx, path. CGPath); // set the fill color [[UIColor redColor] setFill]; [UIColor greenColor] setStroke]; // fill: path that must be closed // that is, stroke and fill // If you only need to draw the edge later, it is best not to use fill CGContextDrawPath (ctx, kCGPathFillStroke); // CGContextFillPath (ctx ); CGContextStrokePath (ctx );}

4. Draw an arc

-(Void) drawRect :( CGRect) rect {// draw an arc // center: center // radius: radius // clockwise: current is yes: clockwise no: counter-clockwise CGPoint center = CGPointMake (125,125); UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter: CGPointMake (125,125) radius: 100 startAngle: 0 endAngle:-M_PI_2 clockwise: NO]; // Add a line to the center [path addLineToPoint: center]; // close the path: from the end of the path to the start point // [path closePath]; // fill, the path is disabled by default, from the end of the path to the start point [path fill];}

5. Draw text

-(Void) drawRect :( CGRect) rect {// ========================================= ====================== NSString * name = @ long GUI daisies; // description text attributes, color, font size NSMutableDictionary * attr = [NSMutableDictionary dictionary]; // font attr [NSFontAttributeName] = [UIFont systemFontOfSize: 15]; // color attr [NSForegroundColorAttributeName] = [UIColor redColor]; // border color attr [NSStrokeColorAttributeName] = [UIColor redColor]; // Border Width attr [NSStrokeWidthAttributeName] = @ 1; // shadow NSShadow * shadow = [[NSShadow alloc] init]; shadow. shadowOffset = CGSizeMake (3, 3); shadow. shadowColor = [UIColor yellowColor]; shadow. shadowBlurRadius = 3; attr [NSShadowAttributeName] = shadow; [name drawInRect: CGRectMake (90,100,100, 50) withAttributes: attr];}

6. Draw a pie chart

During initialization, the system calls the drawRect Method for plotting. However, it is invalid to manually call the drawRect method to reproduce the image. However, the system has prepared the re-painting method for us:

Redraw:setNeedsDisplay

-(Void) drawRect :( CGRect) rect {// Drawing code NSArray * datas = @ [@ 25, @ 25, @ 50]; CGPoint center = CGPointMake (125,125 ); CGFloat r = 100; CGFloat startA = 0; CGFloat angle = 0; CGFloat endA = 0; for (NSNumber * number in datas) {// traverse a data, draw a sector startA = endA; angle = number. intValue/100.0 * M_PI * 2; endA = startA + angle; // describe the arc UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter: center radius: r startAngle: startA endAngle: endA clockwise: YES]; [path addLineToPoint: center]; [[self randomColor] set]; [path fill] ;}// when you click View, redraw-(void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event {[self setNeedsDisplay];} // generate a random color-(UIColor *) randomColor {CGFloat r = arc4random_uniform (256) /255.0; CGFloat g = arc4random_uniform (256)/255.0; CGFloat B = arc4random_uniform (256)/255.0; return [UIColor colorWithRed: r green: g blue: B alpha: 1];}

7. Context Stack

Copy the current context to the top of the stack (the stack is called "graphic context stack "):
void CGContextSaveGState(CGContextRef c)

Replace the context at the top of the stack with the current context:
void CGContextRestoreGState(CGContextRef c)

-(Void) drawRect :( CGRect) rect {// Drawing code // 1. obtain the context CGContextRef ctx = UIGraphicsGetCurrentContext (); // 2. splicing path UIBezierPath * path = [UIBezierPath bezierPath]; // horizontal [path moveToPoint: CGPointMake (10,150)]; [path addLineToPoint: CGPointMake (290,150)]; // 3. add the path to the context CGContextAddPath (ctx, path. CGPath ); // ================================================ ============/// Save the context status CGContextSaveGState (ctx ); // ================================================ ==============/// set the context status CGContextSetLineWidth (ctx, 10); [[UIColor redColor] set]; // 4. render the context, view the context status, and render CGContextStrokePath (ctx) based on the status; // vertical path = [UIBezierPath bezierPath]; [path moveToPoint: CGPointMake (150, 10)]; [path addLineToPoint: CGPointMake (150,290)]; // 3. add the path to the context CGContextAddPath (ctx, path. CGPath ); // ================================================ ==========/// retrieve the saved status from the context state stack, replace the current status CGContextRestoreGState (ctx ); // ================================================ ========/// 4. render the context, view the context status, and render CGContextStrokePath (ctx) according to the status );}

8. Context translation, rotation, and scaling

With matrix operations, all paths drawn to the context can change together.
Zoom

void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

Rotate
void CGContextRotateCTM(CGContextRef c, CGFloat angle)

Translation
void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

-(Void) drawRect :( CGRect) rect {// obtain the context CGContextRef ctx = UIGraphicsGetCurrentContext (); // The splicing path UIBezierPath * path = [UIBezierPath failed: CGRectMake (-100, -50,200,100)]; // matrix operation: Deformation must be performed before the path is added // translation context CGContextTranslateCTM (ctx, 100,100); // rotate CGContextRotateCTM (ctx, M_PI_4 ); // scale CGContextScaleCTM (ctx, 0.5, 0.5); // Add the path to the context CGContextAddPath (ctx, path. CGPath); // render the context CGContextFillPath (ctx );}

9. Add watermarks to images

1. Enable a bitmap-based image Context
void UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)

Size: context size opaque: not transparent Yes NO scale: whether to scale the context. 0 indicates not to scale

2. Obtain the image (UIImage) from the context ):

UIImage* UIGraphicsGetImageFromCurrentImageContext()

3. Terminate the bitmap-based image context:

void UIGraphicsEndImageContext()

-(Void) viewDidLoad {enable a bitmap-based image context void Merge (CGSize size, BOOL opaque, CGFloat scale) [super viewDidLoad]; UIImage * image = [UIImage imageNamed: @ hina]; // creates the bitmap context uigraphicsbeginimagecontextwitexceptions (image. size, NO, 0); [image drawAtPoint: CGPointZero]; // text NSString * str = @ long GUI daisies; [str drawAtPoint: CGPointMake (0, 0) withAttributes: nil]; // generate an image = UIGraphicsGetImageFromCurrentImageContext () based on the context; // disable the context UIGraphicsEndImageContext (); // used to transmit images in the network NSData * data = UIImagePNGRepresentation (image); [data writeToFile: @/Users/apple/Desktop/image.png atomically: YES];}

10. Crop Images

1. Crop the paths drawn up and down (none of the paths beyond this cropping area are displayed ):

void CGContextClip(CGContextRef c)

Train of Thought Analysis
First draw a large circle, in the Set crop area, draw the picture, beyond the crop area automatically crop out.
* Load the old image and obtain the context size based on the old image.
* Determine the ring width borderW
* Context size = size of the new image
* Determine the new context size: newImageW: oldImageW + 2 * borderW newImageH: oldImageH + 2 * borderW,
* Draw a circle:
1. Get the context 2. Add the path to the context 3. Set the color of the circle to the color of the ring 4. Rendering
* Set the crop area, which is the same size as the image, except that x and y are different. x = borderW and y = borderW.
* Draw an old image
* Getting new images
* Disable Context
* Classification, three parameters, image name, ring width, and ring color

+ (UIImage *) imageCircleWithImage :( UIImage *) image borderWidth :( CGFloat) borderWidth borderColor :( UIColor *) borderColor {// set the ring width CGFloat boardW = borderWidth; CGFloat imageW = image. size. width + 2 * boardW; CGFloat imageH = image. size. height + 2 * boardW; // select the shortest size and tangent when only the square can be fully split. CGFloat circleW = imageW> imageH? ImageH: imageW; CGRect rect = CGRectMake (0, 0, circleW, circleW); // 2. Enable image context uigraphicsbeginimagecontextwitexceptions (rect. size, NO, 0.0); // 3. Obtain the current context CGContextRef ctx = UIGraphicsGetCurrentContext (); // 4. UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect: rect]; CGContextAddPath (ctx, path. CGPath); [borderColor set]; CGContextFillPath (ctx); // set the Avatar size rect = CGRectMake (boardW, boardW, image. size. width, image. size. height); // 5. create the cropping path UIBezierPath * clipPath = [UIBezierPath bezierPathWithOvalInRect: rect]; // 6. crop path // based on this path. [clipPath addClip] is not displayed for any part beyond the path; // 7. picture [image drawInRect: rect]; // It cannot be returned directly here. If the context is not disabled, the memory will be consumed. // 8. get new image = UIGraphicsGetImageFromCurrentImageContext (); // 9. disable the context UIGraphicsEndImageContext (); return image ;}

11. Capture the screen

The reason why a View can display things is its internal layer. The View has a layer attribute. drawRect: The method obtains a Layer Graphics Context. Therefore, what you draw is actually drawn to the view layer.

- (void)renderInContext:(CGContextRef)ctx;

// Capture the screen + (UIImage *) imageWithCaptureView :( UIView *) captureView; {// 1. enable the context uigraphicsbeginimagecontextwitexceptions (captureView. bounds. size, NO, 0.0); // 2. obtain the current context CGContextRef ctx = UIGraphicsGetCurrentContext (); // 3. render the Controller layer to the context [captureView. layer renderInContext: ctx]; // 4. retrieve new image UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext (); UIGraphicsEndImageContext (); return newImage ;}

 

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.