Combining two images - ios

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" ?

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.

create UIImage to be a border with color

I am using FSCalendar What I want to do is change the way of showing events. I want to put a coloured rectangle border around the cell with events. I did that by editing the cell background layer and worked fine, but now I realized that it is the wrong place to put my code as updating to the latest version of FSCalendar which will override my changes.
One of what I can access by the calendar delegates is to set image to the cell, So I want to create image as rectange border with the event colour.
Here is an image of what I want:
Any suggessions is appreicated.
Thanks in advance.
This method will draw a bordered rectangle. I would make it class method and put into UIImage category for convenient use.
- (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)imageSize andBorderWidth:(CGFloat)borderWidth fillWithColor:(BOOL)fillWithColor{
UIGraphicsBeginImageContext(imageSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rect = CGRectMake(0, 0, imageSize.width, imageSize.height);
if(fillWithColor) {
[color setFill];
CGContextFillRect(context, rect);
} else {
[color setStroke];
CGContextStrokeRectWithWidth(context, rect, borderWidth);
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
EDIT: Added fillWithColor parameter
You can set border for UIImageView instead of set image as rectange border
cell.imageView.layer.borderColor = [[UIColor redColor] CGColor];
cell.imageView.layer.borderWidth = 1.0f;

Change background color UIImage

I want to capture UIView and save as image. Here is my code
+ (UIImage *)captureView:(UIView *)view {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO];
// CGContextRef context = UIGraphicsGetCurrentContext();
// CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]);
// CGContextFillRect(context, view.bounds);
UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshotImage;
}
It works fine. But I get one issue: I can not change background for that image. It always gets black background.
So, how to change background?
Thanks.
The reason why you cannot change the background for a UIImage is because UIImage does not possess a background attribute. To add a background for which you can change color, you're going to have to create a custom UIView on your own for which the UIImage can be placed on top of. So for example, let's say you wanted to create a function which returns an image with a background of your choice:
- (UIImage* )setBackgroundImageByColor:(UIColor *)backgroundColor withFrame:(CGRect )rect{
// tcv - temporary colored view
UIView *tcv = [[UIView alloc] initWithFrame:rect];
[tcv setBackgroundColor:backgroundColor];
// set up a graphics context of button's size
CGRectGSize gcSize = tcv.frame.size;
UIGraphicsBeginImageContext(gcSize);
// add tcv's layer to context
[tcv.layer renderInContext:UIGraphicsGetCurrentContext()];
// create background image now
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
// [tcv release];
}
// [view drawViewHierarchyInRect:view.frame afterScreenUpdates:NO]; // comment this line
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; // use this line
it gives the actual color of the view's as it is.. if your view's background color is clear color or black color, the image background color will be black color

How to draw image inside a circular bezier path

I am trying to create a custom view to draw a music CD with the album artwork on the CD.
Currently I use core graphics to draw two circular disks inside the drawRect method. The inner disk's colour is set to the background colour of the view to make it look like the inner circle is a hollow circle.
My problem is that I can't draw the UIImage inside the the circular bezier path to get the result that I need.
Here's my drawRect code:
// Draw a CD like view using three drawing operations:
// 1st draw the main disk
// 2nd draw the image if it is set
// 3rd draw the inner disk over the image so that it looks like it is a hollow disk with the image painted on the disk.
// Note:) This view expects its aspect ratio to be set as 1:1
- (void)drawRect:(CGRect)rect
{
// Draw the main Circular CD disk
UIBezierPath* outerRing = [UIBezierPath bezierPathWithOvalInRect:self.bounds];
[self.mainColor setFill];
[outerRing fill];
[self.outerRingColor setStroke];
[outerRing stroke];
// Draw the album image if it is set
if(self.artwork){
[self.artwork drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0];
}
// now draw another smaller disk inside
// this will be a percentage smaller than the whole disk's bounds and will be centered inside it
CGFloat sidePaddingCoord = ((1.0f - INNER_DISK_SIZE_PERCENTAGE) / 2) * self.bounds.size.height;
CGFloat side = INNER_DISK_SIZE_PERCENTAGE * self.bounds.size.width;
UIBezierPath* innerRing = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(sidePaddingCoord, sidePaddingCoord, side, side)];
[self.innerRingColor setFill];
[innerRing fill];
[innerRing stroke];
}
This fills the image as a square. I want the image to be clipped inside the outerRing bezier path so that it looks like a music CD.
I'm sure there is a way to use core graphics to achieve something else besides using the image's drawInRect method. Is there any way to 'clip' the image inside the circular bezier path or only draw inside the bezier path?
I've read really great posts by rob mayoff, UIBezierPath Subtract Path, iOS UIImage clip to paths, many thanks.
Here is an adoption of his code. Keep your creation code of outerRing and innerRing, add them to an array named paths.
[self.paths addObject:outerRing];
[self.paths addObject:innerRing];
Then use this help method.
- (UIImage *)maskedImage
{
CGRect rect = CGRectZero;
rect.size = self.originalImage.size;
UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0);
UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:CGRectInfinite];
[clipPath appendPath:self.paths[1]];
clipPath.usesEvenOddFillRule = YES;
CGContextSaveGState(UIGraphicsGetCurrentContext()); {
[clipPath addClip];
[[UIColor orangeColor] setFill];
[self.paths[0] fill];
} CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIImage *mask = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0); {
CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);
[self.originalImage drawAtPoint:CGPointZero];
}
UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return maskedImage;
}
In drawRect,
UIImage *maskedImage = [self maskedImage];
[maskedImage drawInRect:self.bounds blendMode:kCGBlendModeNormal alpha:1.0];
Try below code:
UIImageView *userImageView= [[UIImageView alloc] initWithFrame:CGRectMake(85, 55.0, 90, 90)];
userImageView.layer.cornerRadius = 90/2;
userImageView.clipsToBounds = YES;
userImageView.layer.borderWidth = 1.0f;
userImageView.layer.borderColor = [UIColor blueColor];
[self.view addSubview:userImageView]; //or add it to the view you want
UIImage *userImage = [UIImage imageNamed:#"<image you want to set>"];
userImageView= [[UIImageView alloc] initWithFrame:CGRectMake(90, 60.0, 80, 80)];
userImageView.image = userImage;
userImageView.layer.cornerRadius = 80/2;
userImageView.clipsToBounds = YES;
userImageView.layer.borderWidth = 1.0f;
userImageView.layer.borderColor = [UIColor blueColor;
[self.view addSubview:userImageView]; //or add it to the view you want

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