Drawing a transparent circle with Core Graphics - core-graphics

I am trying to draw a transparent circle on the screen, where the screen has a black background with 0.5 alpha. However my transparent circle is not clearing the black background. How could I do that? If I wanted a transparent rectangle I could use CGContextClearRect(context,rect) and it clears the background. Any ideas for a circle?
CGContextRef context = UIGraphicsGetCurrentContext();
// Fill the screen with black 0.5 alpha color
CGContextSetRGBFillColor(context,0., 0., 0., 0.5);
CGContextFillRect(context, CGRectMake(0.0, 0.0, 320, CGRectGetHeight(self.frame)));
CGRect circleFrame = CGRectMake(0, 0, 320, 320);
// Draw a circle with a transparent fill
CGContextSetFillColor(context, CGColorGetComponents([UIColor clearColor].CGColor));
CGContextAddEllipseInRect(context, circleFrame);
CGContextFillPath(context);

First set up the path of your circle, then call CGContextClip(), then draw your background.

Related

drawRect doesn't draw rect - Objective-C

I just want to draw a rect on a view. This is my code in my UIView subclass:
- (void)drawRect:(CGRect)rect
{
context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 255.0/255.0, 0.0/255.0, 0.0/255.0, 1);
CGContextAddRect(context, (CGRectMake(20, 20, 20, 20)));
}
When I run it no rect is drawn. What's wrong?
CGContextAddRect just adds a rectangular path to the context. You need to stroke or fill the path as well using CGContextFillPath or CGContextStrokePath.
You can also fill a rect directly with UIRectFill or CGContextFillRect.

Lines drawn with core graphics that are set to the same width sometimes vary in size when drawn

Here is a picture of two lines drawn in a UITableViewCell with the same function, and same width, and color
As you can see the bottom line is a lot thicker than the other line.
The code I am using for drawing:
[CSDrawing drawLineWithColor:[UIColor blackColor] width:1.0 yPosition:1.0 rect:rect];
[CSDrawing drawLineWithColor:[UIColor blackColor] width:1.0 yPosition:CGRectGetMaxY(rect) - 3.0 rect:rect]; // draw a line on top and bottom
+(void)drawLineWithColor:(UIColor *)color width:(CGFloat)width yPosition:(CGFloat)yPosition rect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextMoveToPoint(context, 0.0, yPosition);
CGContextAddLineToPoint(context, CGRectGetMaxX(rect), yPosition);
CGContextSetStrokeColorWithColor(context, color.CGColor);
CGContextSetLineWidth(context, width);
CGContextStrokePath(context);
CGContextRestoreGState(context);
}
The problem was with the backgroundView being stretched to fit the content of the cell when the cell was being reused. When the cell was bigger the pixels were stretched. This is solved be setting the contentMode property to UIViewContentModeRedraw

How do i get rid of a line drawn by drawRect to disappear .05 seconds after the user touches the screen?

I have the touchesBegan void before this which triggers this event,
but i need this line to show, wait for so many seconds, then disappear:
- (void)drawRect:(CGRect)rect {
// Drawing code
//Make a simple rectangle and fill background BLUE with half Opeque
CGContextRef context = UIGraphicsGetCurrentContext();
//[[UIColor blueColor] set];
//CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
//rect = CGRectMake(20, 20, 40, 40);
//CGContextFillRect(context, rect);
//Make a simple RED line from 0,0 to 100, 100 in a FRAME
//CGContextSetRGBFillColor(context, 100.0, 0.0, 0.0, 1.0);
[[UIColor redColor] set];
CGContextMoveToPoint(context, _spaceShip.center.x, _spaceShip.center.y);
CGContextAddLineToPoint( context, nextLocX, nextLocY);
CODE FOR MAKING THE LINE DISAPPEAR
}
Redraw the frame without that line would be the obvious solution.
Draw over it in the background color would be a less-pretty solution that might in some cases run faster.

Objective-c core graphics draw rotated image not working

i am trying to draw rotated image with following code
CGLayerRef layer=CGLayerCreateWithContext(context,CGSizeMake(brush.size.width*2,brush.size.height*2), NULL);
CGContextRef tmp=CGLayerGetContext(layer);
CGContextDrawImage(tmp,CGRectMake(brush.size.width/2, brush.size.height/2, brush.size.width, brush.size.height), brush.CGImage);
CGContextSetFillColorWithColor(tmp, [UIColor clearColor].CGColor);
CGContextSetBlendMode(tmp, kCGBlendModeClear);
CGContextFillRect(tmp, CGRectMake(0, 0, 2*brush.size.width, 2*brush.size.height));
CGContextSetBlendMode(tmp, kCGBlendModeNormal);
CGContextTranslateCTM(tmp, -brush.size.width/2, -brush.size.height/2);
CGContextRotateCTM(tmp, angle);
CGContextTranslateCTM(tmp, brush.size.width/2, brush.size.height/2);
CGContextDrawImage(tmp,CGRectMake(brush.size.width/2, brush.size.height/2, brush.size.width, brush.size.height), brush.CGImage);
I want to place image at the center of layer (image is square)
try the rotation then the translation

Saving 2 UIImages to one while saving rotation, resize info and its quality

I want to save 2 UIImages that are moved, resized and rotated by user. The problem is i dont want to use such function as any 'printscreen one', because it makes both images to lose a lot from their quality (resolution).
Atm i use something like this:
UIGraphicsBeginImageContext(image1.size);
[image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
However ofc it just adds two images, their rotation, resizing and moving isn't operated here. Can anybody help with considering these 3 aspects in coding? Any help is appreciated!
My biggest thanks in advance :)
EDIT: images can be rotated and zoomed by user (handling touch events)!
You have to set the transform of the context to match your imageView's transform before you start drawing into it.
i.e.,
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);
// Draw the image into the context
CGContextDrawImage(context, CGRectMake(-imageView.image.size.width/2, -imageView.image.size.height/2, imageView.image.size.width, imageView.image.size.height), imageView.image.CGImage);
// Get an image from the context
rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];
and check out Creating a UIImage from a rotated UIImageView.
EDIT: if you don't know the angle of rotation of the image you can get the transform from the layer property of the UIImageView:
UIGraphicsBeginImageContext(rotatedImageView.image.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform transform = rotatedImageView.transform;
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);
// Draw the image into the context
CGContextDrawImage(context, CGRectMake(0, 0, rotatedImageView.image.size.width, rotatedImageView.image.size.height), rotatedImageView.image.CGImage);
// Get an image from the context
UIImage *newRotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];
UIGraphicsEndImageContext();
You will have to play about with the transform matrix to centre the image in the context and you will also have to calculate a bounding rectangle for the rotated image or it will be cropped at the corners (i.e., rotatedImageView.image.size is not big enough to encompass a rotated version of itself).
Try this:
UIImage *temp = [[UIImage alloc] initWithCGImage:image1 scale:1.0 orientation: yourOrientation];
[temp drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
Similarly for image2. Rotation and resizing are handled by orientation and scale respectively. yourOrientation is a UIImageOrientation enum variable and can have a value from 0-7(check this apple documentation on different UIImageOrientation values). Hope it helps...
EDIT: To handle rotations, just write the desired orientation for the rotation you require. You can rotate 90 deg left/right or flip vertically/horizontally. For eg, in the apple documentation, UIImageOrientationUp is 0, UIImageOrientationDown is 1 and so on. Check out my github repo for an example.