UIBezierPath clip an UIIimage - ios

I have a UIBezierPath and I want to get a PNG image from a source image which is shaped like path.
UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, 0);
[bpath addClip];
[sourceImage drawAtPoint:CGPointZero];
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
But the maskedImage is empty. My path seems to be valid as I tested a fill using the path. Please advice how I can get the part of an image which is shaped liked the UIBezierPath

Your code is fine, the problem is either your clipping mask or your image. I just tried the below and it worked flawlessly:
UIImage *sourceImage = [UIImage imageNamed:#"example"];
UIBezierPath *bpath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height) cornerRadius:50];
UIGraphicsBeginImageContextWithOptions(sourceImage.size, NO, 0);
[bpath addClip];
[sourceImage drawAtPoint:CGPointZero];
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
The first two lines are mine; the last five are yours. The results looks exactly as I would expect, so either there's a problem loading your image (put a breakpoint when drawing and inspect the results using Quick Look), or your mask isn't what you think it is.
Fun fact: UIBezierPath is also compatible with Quick Look, so you should be able to inspect the contents of bpath in the debugger to make sure it is what you think it is. Make sure your path is a sensible size given the size of your image!

I figured it out. I wrote my solution here
The key was to draw the image as
UIGraphicsPushContext(context);
UIBezierPath *bpath = [UIBezierPath bezierPath];
// Add lines to path
[bpath closePath];
[bpath addClip];
[_overlayImage drawInRect:theRect blendMode:kCGBlendModeMultiply alpha:0.4];
UIGraphicsPopContext();

Related

UIBezierPath : Make image of drawing only

I am creating an image from free hand drawing using below code :
UIGraphicsBeginImageContext(self.bounds.size);
for (UIBezierPath *path in self.pathArray) {
[self.lineColor setStroke];
[path stroke];
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I want to take image of only black lines (drawing) not the entire view's. View is size of 300x300. But if my drawing is in 50x50 then I want to focus on that part only.
I tried with
UIGraphicsBeginImageContext(signPath.bounds.size);
signPath is UIBezierPath object. But with this I am getting blank image.
Any suggestions ?
ok I figured it out.
UIGraphicsBeginImageContext(signPath.bounds.size);
By this way I was creating image context's size only and origin was missing.
So I need to create image context with x and y (origins).
I have origin in UIBezierPath with size.
Code :
CGSize size = signPath.bounds.size;
size = CGSizeMake(size.width + 10, size.height + 10);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-signPath.bounds.origin.x + 5, -signPath.bounds.origin.y + 5));
[self.layer renderInContext:c];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
I have given static values for some padding (given some space) while creating the image.
Not sure if this is the standard way, but it solved my problem and I am able to create image of hand drawing in a 500x500 view.
Now I am getting image of the my free hand drawing (Strokes) not for the entire view.

iOS UIImage with border has a thick corner-radius

I'm attempting to build a UIImage in code using CoreGraphics (via PaintCode) that has a border and a corner radius. I'm finding that the image has a noticeably thicker border around the corner. This seems like it would either be an iOS bug or something that I'm completely missing. Please advise.
Code:
CGRect rect = CGRectMake(0, 0, 53, 100);
//// UIGraphics for UIImage context
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
//// Rectangle Drawing
UIBezierPath *rectanglePath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
[backgroundColor setFill];
[rectanglePath fill];
[borderColor setStroke];
rectanglePath.lineWidth = 1.4;
[rectanglePath stroke];
//// UIBezierPath to Image
CGContextAddPath(context, rectanglePath.CGPath);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsPopContext();
UIGraphicsEndImageContext();
return image;
Image:
Here's what a lineWidth of 1 and width of 60 looks like, it still seems a little thick:
For those of you following along at home:
Thanks to the helpful #PixelCutCompany I need to inset the bounds for the UIBezierPath so that the border doesn't exceed the frame of the image I am drawing.
Modified the code as follows for a lineWidth of 1.
CGRect boundedRectForRadius = CGRectMake(1, 1, 58, 98);
UIBezierPath *rectanglePath = [UIBezierPath bezierPathWithRoundedRect:boundedRectForRadius cornerRadius:cornerRadius];
Without this, it was cropping the image as so:
The problem also can be in shift real screen pixels coordinates.
Please check this discussion for more details:
Core Graphics is not drawing a line at the correct width

Combining two images

I'm trying to combine two UI Images and make a new image called mainImage. One of the images is a solid background, backgroundImage, while the other is a curve created by a path, brushimage. For what I have right now the background image draws but the curve image won't. This first method creates an image for the curve image with a path.
- (void)drawBrezierPath:(UIBezierPath *)thePath onto:(UIImage *)image {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
[image drawAtPoint:CGPointZero];
[self.brushColor setStroke];
[thePath stroke];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
This one creates the background:
- (void)drawBackground
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
UIBezierPath *rectpath = [UIBezierPath bezierPathWithRect:self.bounds];
[self.backgroundColor setFill];
[rectpath fill];
backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
And then they are combined using this:
- (void)drawMainImage {
UIGraphicsBeginImageContext(self.frame.size);
//[self drawBackground];
[backgroundImage drawInRect:self.frame];
[brushImage drawInRect:self.frame];
mainImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
But only the background shows up. When I comment out the line that draws the background then the line is shown but it doesn't draw when the background gets drawn. When I switch the order that the background/brushimage are drawn it doesn't make a difference the brushImage still doesn't show up.
Thanks!
you merge brushImage and BackgroundImage in third function, but you create "image" instead of "brushImage" in first function, shouldn't you set it to "brushImage" ?

iphone - Tinting/shading/glowing an animated UIImage

I'm currently using [UIImage animatedImageNamed:#"..." duration:1.0f] to animate a series of PNG images in my iOS 7 app.
When the image is still, I use UIGraphicsGetImageFromCurrentImageContext() as follows:
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
{
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
[color setFill];
[path fillWithBlendMode:kCGBlendModeSourceAtop alpha:1.0];
image = UIGraphicsGetImageFromCurrentImageContext();
} UIGraphicsEndImageContext();
...and then CAAnimation to glow/tint/shade the image mask. For the animated image, though, is there a way to animate the mask so that it follows the animated PNG? (By "mask" I mean shape or silhouette of the image content that I'm animating.)

iOS: Inverse UIBezierPath (bezierPathWithOvalInRect)

I have an jpg Image with a round object in a rect and want to make the envoirement of the round object transparent...
(Remove red area in this example)
With the help of this iOS make part of an UIImage transparent and "UIBezierPath bezierPathWithOvalInRect" i've got a little success, but this make a path around my object, and I need to invert it, to make the outside and not the inside of the path transparent..
Im not shure where I have to change my code to get the right result..
Here is my code:
//BezierPath
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 100)];
// Create an image context containing the original UIImage.
UIGraphicsBeginImageContext(_imgTemp.image.size);
[_imgTemp.image drawAtPoint:CGPointZero];
// Clip to the bezier path and clear that portion of the image.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context,bezierPath.CGPath);
CGContextClip(context);
CGContextClearRect(context,CGRectMake(0,0,self._imgTemp.image.size.width,self._imgTemp.image.size.height));
// Build a new UIImage from the image context.
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self._imgTemp.image = newImage;
Anybody got the resolving?
To only draw within the black circle you should move [_imgTemp.image drawAtPoint:CGPointZero]; to after CGContextClip(context); and then remove the CGContextClearRect( ... ) call entirely:
//BezierPath
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 100, 100)];
// Create an image context containing the original UIImage.
UIGraphicsBeginImageContext(_imgTemp.image.size);
// Clip to the bezier path and clear that portion of the image.
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context,bezierPath.CGPath);
CGContextClip(context);
// Draw here when the context is clipped
[_imgTemp.image drawAtPoint:CGPointZero];
// Build a new UIImage from the image context.
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self._imgTemp.image = newImage;

Resources