I want to draw line between two points. Here is my code. but context memory is 0.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, color);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 300, 400);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
You need to call your code within a UIView subclass in the method drawRect:.
UIGraphicsGetCurrentContext() will get NULL (0) when your are not in a drawing context.
You might also check the docs.
Here is a very useful tutorial for your need.
http://trailsinthesand.com/exploring-iphone-graphics-part-1/
Go through it once..!
Related
So I can't seem to be able to draw 2 CGMutablePathRef. Here's the code:
CGRect mainRect = CGRectMake(2, 2, rect.size.width-4, 210);
CGMutablePathRef mainPathRef = createRoundedRectForRect(mainRect, 4);
if (self.imageExists_){
[[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0] set];
CGContextAddPath(context, mainPathRef);
CGContextClip(context);
UIGraphicsBeginImageContext(mainRect.size);
//need to flip the images to that it is drawn appropriately as CALayer uses a different coordinate system
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0.0, 210);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, mainRect, self.highlightItem_.highlightStoryImage.CGImage);
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[scaledImage drawAtPoint:CGPointMake(0, 0)];
CGContextRestoreGState(context);
this draws the image just fine on the path I specified, clipped. But then I want to draw another rounded rect below it, so I did:
[[UIColor colorWithRed:0 green:0 blue:0 alpha:1.0] set];
CGFloat colors [] = {
0.20, 0.20, 0.20, 1.0,
0.17, 0.17, 0.17, 1.0
};
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
CGColorSpaceRelease(baseSpace), baseSpace = NULL;
CGContextSaveGState(context);
CGRect commentRect = CGRectMake(2, 215, rect.size.width-4, rect.size.height - 215);
CGMutablePathRef pathRef = createRoundedRectForRect(commentRect, 3);
CGContextAddPath(context, pathRef);
CGContextClip(context);
CGPoint startPoint = CGPointMake(CGRectGetMidX(commentRect), CGRectGetMinY(commentRect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(commentRect), CGRectGetMaxY(commentRect));
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient), gradient = NULL;
CGContextRestoreGState(context);
CGContextAddPath(context, pathRef);
CGContextDrawPath(context, kCGPathStroke);
Any idea why this doesn't work?
You've clipped the drawing to the first rect, but haven't reset the clipping path before drawing the second time. You need to save the graphics state before the first clipping path is invoked, I believe.
Your first snippet should look something like this:
CGContextSaveGState(...);
CGContextAddPath(...);
CGContextClip(...);
UIGraphicsBeginImageContext(...);
... rest of your drawing code...
CGContextRestoreGState(...);
and then the second code snippet.
I have integrate draw line in my application i have not used OpenGL or any other similar framework.
So now i want to give glow effect to their lines so how can i give it ?
Thanks in advance.
Set the shadow in your graphics context to have a zero size offset, a blur of around 6-10 (change according to taste) and the same colour as your stroke colour. This will give all subsequent drawing a glow effect. The command is
CGContextSetShadowWithColor()
Documented here.
-(void)drawRect:(CGRect)rect{
[curImage drawAtPoint:CGPointMake(0, 0)];
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
// Use QuadCurve is the key
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
//------------ Glow Lines ----------
if (appDel.BrushType == 201) // (201 is glow brush type)
{
CGContextSetLineWidth(context, 7);
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
CGFloat components[4]={appDel.R_color/255.0,appDel.G_color/255.0,appDel.B_color/255.0,1.0};
CGColorRef color1 = CGColorCreate(space, components);
CGContextSetShadowWithColor(context, CGSizeMake( 0.0, 0.0 ), 15, color1);
CGContextStrokePath(UIGraphicsGetCurrentContext());
}
//--------------
CGContextStrokePath(context);
[super drawRect:rect];
[curImage release];
}
I am new to Objective-C and iOS development. I have a view with some figures drawn by core drawing. Now I want to fill those shapes with color and I don't know the path or context of shape. Does Objective-C have any function like flood-fill or put-pixel so that by having only the stroke color I can fill any shape inside my view.
-(void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 4.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {1.0, 0.0, 0.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, color);
CGContextMoveToPoint(context, 50, 0);
CGContextAddLineToPoint(context, 0,320);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextSetRGBFillColor(context, 0, 255, 0, 1.0);
CGContextMoveToPoint(context, 100, 100);
CGContextAddLineToPoint(context, 150, 150);
CGContextAddLineToPoint(context, 100, 200);
CGContextAddLineToPoint(context, 50, 150);
CGContextAddLineToPoint(context, 100, 100);
CGContextStrokePath(context);
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect rectangle = CGRectMake(60,170,200,80);
CGContextAddEllipseInRect(context, rectangle);
CGContextStrokePath(context);
}
This will make a circle and a square with some common region. I want a particular region to fill with color when a user taps that region.
So you are looking for flood fill in Objective C.
This is my implementation of Scan Line Flood Fill Algorithm.
Github : UIImageScanlineFloodfill
If you want to learn basic of flood fill:
Lode's Computer Graphics Tutorial Flood Fill
I hope this will help you.
Put your drawing code in the question and I can give you a specific answer.
Normally you just need to set a fill color using
[[UIColor redColor] setFill];
And any shapes you draw your core graphics will be filled with that color automatically.
Try this command:-
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
Core Graphics is closely tied to UIView and its drawRect: method and has a C interface. As you point out, you always draw in the current graphics context. I can think of 2 approaches: (1) When the user taps myView, set a property like myView.pointTapped, and in drawRect: find the shape to fill, set a fill color, and fill the closed path using GGGeometry methods.
There is an objective-C alternative: (2) Take a look at UIBezierPath. It's not as comprehensive as drawing in Core Graphics but it can be used in your ViewController implementation.
I want to draw a curved line with arrow between two points using the Quartz Core framework in an iPhone Application. How to do that or any what classes are available to do that ?
You can change the co-ordinates as you want
- (void)drawRect:(CGRect)rect {
//DRAW CURVE
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGContextMoveToPoint(context, 100, 100);
CGContextAddArcToPoint(context, 100,200, 300,200, 100);
CGContextStrokePath(context);
//DRAW LINE
CGContextSetLineWidth(context, 2.0);
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0, 0.0, 1.0, 1.0};
CGColorRef color = CGColorCreate(colorspace, components);
CGContextSetStrokeColorWithColor(context, color);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, 300, 400);
CGContextStrokePath(context);
CGColorSpaceRelease(colorspace);
CGColorRelease(color);
}
I want to preserve previous drawing in drawRect (the system clears it down each time) and it seems that the way to go is to use a bitmap context and sure enough, this works except that now my colour is gone leaving only black and white instead.
Here is my "static" context
-(id)initWithCoder:(NSCoder *)aDecoder {
...
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
contextRef = CGBitmapContextCreate(NULL,
320,
640,
8,
320*4,
colorSpace,
kCGImageAlphaPremultipliedLast);
...
}
and here is my replacement context:
-(void)drawRect:(CGRect)rect {
myDrawRoutine();
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, rect, CGBitmapContextCreateImage(contextRef));
}
And this is the draw routine's guts:
...
// CGContextRef context = UIGraphicsGetCurrentContext();
CGContextRef context = contextRef;
if( !(context) )
return;
CGContextSetFillColor(context, CGColorGetComponents([co CGColor]));
CGContextSetStrokeColor(context, CGColorGetComponents([co CGColor]));
CGContextFillEllipseInRect(context, CGRectMake((*i)->x,
(*i)->y,
(*i)->diam,
(*i)->diam));
...
}
Thanks tonclon
That has made a hell of an increase in speed :)
But it still draws in black and white :(
Here is the above code + modifications...
Here is my "static context":
-(id)initWithCoder:(NSCoder *)aDecoder {
...
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
contextRef = CGBitmapContextCreate(NULL,
320,
640,
8,
320*4,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
cglayer = CGLayerCreateWithContext(contextRef, CGSizeMake(320.0f, 640.0f), NULL);
contextRef = CGLayerGetContext(cglayer);
...
}
and here is my "replacement context" i.e. the cglayer is used instead (the context is no longer replaced).
-(void)drawRect:(CGRect)rect {
for(std::vector<Body*>::iterator i = bodyVec.begin(); i < bodyVec.end(); ++i)
move(i);
CGContextRef context = UIGraphicsGetCurrentContext();
// CGContextDrawImage(context, rect, CGBitmapContextCreateImage(contextRef));
CGContextDrawLayerInRect(context, rect, cglayer);
}
(The "draw routine's guts" remain the same.)
At last! Thanks to this thread
Extracting rgb from UIColor
I got the answer - use CGContextSetRGBFillColor instead and then feed it with the RGB from CGColorGetComponents indirectly.
CGColorRef color = [co CGColor];
int numComponents = CGColorGetNumberOfComponents(color);
CGFloat red;
CGFloat green;
CGFloat blue;
CGFloat alpha;
if (numComponents == 4)
{
const CGFloat *components = CGColorGetComponents(color);
red = components[0];
green = components[1];
blue = components[2];
alpha = components[3];
}
// CGContextSetFillColor(context, CGColorGetComponents([co CGColor]));
// CGContextSetStrokeColor(context, CGColorGetComponents([co CGColor]));
CGContextSetRGBFillColor(context, red, green, blue, alpha);
CGContextSetRGBStrokeColor(context, red, green, blue, alpha);
CGContextFillEllipseInRect(context, CGRectMake((*i)->x,
(*i)->y,
(*i)->diam,
(*i)->diam));
}