iOS, Draw text with stroke on UIImage - ios

I am currently drawing text onto a UIImage which appears in an AnnotationView in an iOS Map - custom icons which appear at certain long/lat coordinates. Works well. However, I would like to draw this text with a white stroke (you might call it an outline).
// Draw text and add to a UIImage iOS 5/6
+ (UIImage*)drawText:(NSString*)string inImage:(UIImage*)image atPoint:(CGPoint)point {
UIFont *font = [UIFont boldSystemFontOfSize:12];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[[UIColor whiteColor] set];
[string drawInRect:CGRectIntegral(rect) withFont:font];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

NSAttributedString is definitely the way to go, especially if you want it to work in iOS7. For your example, you can just replace the two text blocks with the following:
// draw stroke
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:font forKey:NSFontAttributeName];
[attributes setObject:[NSNumber numberWithFloat:4] forKey:NSStrokeWidthAttributeName];
[attributes setObject:[UIColor whiteColor] forKey:NSStrokeColorAttributeName];
[self.text drawInRect:rect withAttributes:attributes];
// draw fill
[attributes removeObjectForKey:NSStrokeWidthAttributeName];
[attributes removeObjectForKey:NSStrokeColorAttributeName];
[attributes setObject:[UIColor blackColor] forKey:NSForegroundColorAttributeName];
[self.text drawInRect:rect withAttributes:attributes];

Took more time and effort than I thought, but in case anyone out there is looking for the same solution...Apparently not working under iOS7 and will update when I find the answer
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIImage *backgroundImage = [UIImage imageNamed:#"abstract_art_masterpiece_b.jpg"];
UIImage *textWithStrokeImage = [RJViewController drawTextWithStroke:#"unit 111"];
UIImage *image = [RJViewController placeImage:textWithStrokeImage onImage:backgroundImage];
self.imageView.image = image;
}
+ (UIImage*)placeImage:(UIImage*)image1 onImage:(UIImage*)image2 {
CGSize size = image2.size;
if ([UIScreen instancesRespondToSelector:#selector(scale)] && [[UIScreen mainScreen] scale] == 2.0f) {
UIGraphicsBeginImageContextWithOptions(size, NO, 2.0f);
} else {
UIGraphicsBeginImageContext(size);
}
[image2 drawAtPoint:CGPointMake(0, 0)];
[image1 drawAtPoint:CGPointMake(0, 0)];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
+ (UIImage*)drawTextWithStroke:(NSString*)string {
// set rect, size, font
CGRect rect = CGRectMake(0, 0, 88, 24);
CGSize size = CGSizeMake(rect.size.width, rect.size.height);
UIFont *font = [UIFont fontWithName:#"Helvetica-Bold" size:12];
// retina display, double resolution
if ([UIScreen instancesRespondToSelector:#selector(scale)] && [[UIScreen mainScreen] scale] == 2.0f) {
UIGraphicsBeginImageContextWithOptions(size, NO, 2.0f);
} else {
UIGraphicsBeginImageContext(size);
}
CGContextRef context = UIGraphicsGetCurrentContext();
// draw stroke
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 4.0);
CGContextSetTextDrawingMode(context, kCGTextStroke);
[string drawInRect:CGRectIntegral(rect) withFont:font];
// draw fill
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextSetTextDrawingMode(context, kCGTextFill);
[string drawInRect:CGRectIntegral(rect) withFont:font];
// convert to image and return
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

Related

I need round and text on UIImage, i already achieved square with text but not able to make it round

I need round and text on the round on UIImage like this Image
Sample Image here
Here is my code which i achieved already but with square not in round, i need round around the text.
+(UIImage*)drawText:(NSString*)text inImage:(UIImage*)image atPoint:(CGPoint)point
{
UIFont *font = [UIFont boldSystemFontOfSize:50];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x - 10, point.y - 10, image.size.width, image.size.height);
[text drawInRect:CGRectIntegral(rect) withAttributes:#{NSFontAttributeName:font,NSBackgroundColorAttributeName:[UIColor colorWithRed:0.26 green:0.32 blue:0.59 alpha:1.0],NSForegroundColorAttributeName:[UIColor whiteColor]}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Thanks in advance.
Do something like that:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.imgview.image = [ViewController drawText:#"iOS" inImage:[UIImage imageNamed:#"eye"] atPoint:CGPointMake(30 , 30)];
self.imgview.layer.cornerRadius = self.imgview.frame.size.height/2;
self.imgview.clipsToBounds = YES;
}
+ (UIImage*)drawText:(NSString*)text inImage:(UIImage*)image atPoint:(CGPoint)point
{
UIFont *font = [UIFont boldSystemFontOfSize:20];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x - 10, point.y - 10, image.size.width, image.size.height);
[text drawInRect:CGRectIntegral(rect) withAttributes:#{NSFontAttributeName:font,NSBackgroundColorAttributeName:[UIColor colorWithRed:0.26 green:0.32 blue:0.59 alpha:1.0],NSForegroundColorAttributeName:[UIColor whiteColor]}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
UPDATE
For this you have to add some more logic like below.
- (void)viewDidLoad {
[super viewDidLoad];
self.imgview.image = [ViewController drawText:#"iOS Dev" inImage:[UIImage imageNamed:#"Lion"] bgCircleRect:CGRectMake(15, 15, 100, 100)];
}
+ (UIImage*)drawText:(NSString*)text inImage:(UIImage*)image bgCircleRect:(CGRect) bgCircleRect
{
UIFont *font = [UIFont boldSystemFontOfSize:20];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(bgCircleRect.origin.x+10, bgCircleRect.origin.y+35, bgCircleRect.size.width, bgCircleRect.size.height);
UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect: bgCircleRect cornerRadius: 50];
[UIColor.redColor setFill];
[path fill];
[text drawInRect:CGRectIntegral(rect) withAttributes:#{NSFontAttributeName:font,NSBackgroundColorAttributeName:[UIColor redColor],NSForegroundColorAttributeName:[UIColor whiteColor]}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Output
For making the UIImageView round, First check whether the length and width is same, then apply the following code in the viewDidLoad()
yourpic.layer.cornerRadius = yourpic.frame.size.width / 2;
yourpic.clipsToBounds = YES;
I think this will do.
I think you are looking for corner radius :
+(void)drawText:(NSString*)text inImage:(UIImage*)image atPoint:(CGPoint)point{
UIImageView *imageView = [[UIImageView alloc] init];
UIFont *font = [UIFont boldSystemFontOfSize:50];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x - 10, point.y - 10, image.size.width, image.size.height);
[text drawInRect:CGRectIntegral(rect) withAttributes:#{NSFontAttributeName:font,NSBackgroundColorAttributeName:[UIColor colorWithRed:0.26 green:0.32 blue:0.59 alpha:1.0],NSForegroundColorAttributeName:[UIColor whiteColor]}];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageView.center = point;
imageView.image = newImage; }
Add image to imageView and add that as subView to your main view

how to Call static Method which Accept 3 Parameters

How can I call this function?
I am trying to call this function from -viewDidLoad.
I tried [circularImageWithImage(imageView.image, myclor, 0.2)];
static UIImage *circularImageWithImage(UIImage *inputImage,
UIColor *borderColor,
CGFloat borderWidth)
{
CGRect rect = (CGRect){ .origin=CGPointZero, .size=inputImage.size };
UIGraphicsBeginImageContextWithOptions(rect.size, NO, inputImage.scale); {
// Fill the entire circle with the border color.
[borderColor setFill];
[[UIBezierPath bezierPathWithOvalInRect:rect] fill];
// Clip to the interior of the circle (inside the border).
CGRect interiorBox = CGRectInset(rect, borderWidth, borderWidth);
UIBezierPath *interior = [UIBezierPath bezierPathWithOvalInRect:interiorBox];
[interior addClip];
[inputImage drawInRect:rect];
}
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
You can try with this code.
UIImage *image = [UIImage imageNamed:#"yourImage.png"];
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];//set your frame
//imageView.center = self.view.center;
UIImage *modifiedImage = circularImageWithImage(image, [UIColor redColor], 1.2);//border width >= 1.0 is better. Otherwise you may not see this
imageView.image = modifiedImage;
[self.view addSubview:imageView];
UIImage *sample = circularImageWithImage(imageView.image, myclor, 0.2);

iOS CGContextRef Draw Stroke Color and Border Text on UIImage

I'm trying to implement draw stroke text with color and border on UIImage but I can't get the solution.
I have used this THLabel for stroke and border of text and it works fine but only when I copy that code into draw image so at that time it's working for me.
Please see the screen shot for the same. Any suggestions?
Draw Text on UIImage Method :
- (UIImage *) drawText:(NSString*)text
inImage:(UIImage*)image
atPoint:(NSString *)location{
CGFloat fontSize = image.size.width*3/30.0;
NSString *fontName = #"Arial";
int w = image.size.width;
int h = image.size.height;
UIFont *font=[UIFont fontWithName:fontName size:fontSize];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
int textFrameY = 25;
int textFrameX = 5;
CGSize aSize = [text sizeWithFont:font];
CGRect rect = CGRectMake(textFrameX,textFrameY, 80, 30);
CGSize lSize = [location sizeWithFont:font];
CGRect rect1 = CGRectMake(image.size.width-lSize.width-fontSize-textFrameX, h-(fontSize*3)-textFrameY, w, h);
[[UIColor blackColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), rect1);
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
[[UIColor whiteColor] set];
[text drawInRect:CGRectIntegral(rect) withFont:font];
[location drawInRect:CGRectIntegral(rect1) withFont:font];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;}
THLabel code for stroke color and border for text method:
// Demonstrate stroke.
self.label3.strokeColor = kStrokeColor;
self.label3.strokeSize = kStrokeSize;

Create UIImage from a UIImageView

I create a UIImageView with two UILabel as subviews of it:
UIImageView *img=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, [[UIScreen mainScreen] bounds].size.height)];
img.backgroundColor=self.view.backgroundColor;
UILabel *textOne=[[UILabel alloc]initWithFrame:CGRectMake(10, 10, 290, 250)];
textOne.text=_textOneLabel.text;
textOne.textColor=_textOneLabel.textColor;
UILabel *textTwo = [[UILabel alloc] initWithFrame:CGRectMake(100,180,200,100)];
textTwo.text=_textTwoLabel.text;
textTwo.textColor=_textTwoLabel.textColor;
[img addSubview:textOne];
[img addSubview:textTwo];
UIImageWriteToSavedPhotosAlbum(img.image, nil, nil, nil); //img.image is null
I want to create a UIImage to save it in the camera roll with the UIImageView and the 2 created UILabel. img.image returns null because there is no image assigned to the UIImageView.
Do you have an idea of how achieving that?
Use below method to convert your UIImageView to UIImage.
UIImage *image = [self ChangeImageViewToImage:img];
//Method
-(UIImage *) ChangeImageViewToImage : (UIImageView *) view{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
This should help you
/* Creates an image with a home-grown graphics context, burns the supplied string into it. */
- (UIImage *)burnTextIntoImage:(NSString *)text :(UIImage *)img {
UIGraphicsBeginImageContext(img.size);
CGRect aRectangle = CGRectMake(0,0, img.size.width, img.size.height);
[img drawInRect:aRectangle];
[[UIColor redColor] set]; // set text color
NSInteger fontSize = 14;
if ( [text length] > 200 ) {
fontSize = 10;
}
UIFont *font = [UIFont boldSystemFontOfSize: fontSize]; // set text font
[ text drawInRect : aRectangle // render the text
withFont : font
lineBreakMode : UILineBreakModeTailTruncation // clip overflow from end of last line
alignment : UITextAlignmentCenter ];
UIImage *theImage=UIGraphicsGetImageFromCurrentImageContext(); // extract the image
UIGraphicsEndImageContext(); // clean up the context.
return theImage;
}

saving uilabel and uiimageview as uiimage

I'm trying to add text to an image but adding a uilabel as subview to a uiimageview.
I already did that but I want to save them as an image;
I'm using render in context but it's not working.
here's my code:
UIImage * img = [UIImage imageNamed:#"IMG_1650.JPG"];
float x = (img.size.width/imageView.frame.size.width) * touchPoint.x;
float y = (img.size.height/imageView.frame.size.height) * touchPoint.y;
CGPoint tpoint = CGPointMake(x, y);
UIFont *font = [UIFont boldSystemFontOfSize:30];
context = UIGraphicsGetCurrentContext();
UIGraphicsBeginImageContextWithOptions(img.size, YES, 0.0);
[[UIColor redColor] set];
for (UIView * view in [imageView subviews]){
[view removeFromSuperview];
}
UILabel * lbl = [[UILabel alloc]init];
[lbl setText:txt];
[lbl setBackgroundColor:[UIColor clearColor]];
CGSize sz = [txt sizeWithFont:lbl.font];
[lbl setFrame:CGRectMake(touchPoint.x, touchPoint.y, sz.width, sz.height)];
lbl.transform = CGAffineTransformMakeRotation( -M_PI/4 );
[imageView addSubview:lbl];
[imageView bringSubviewToFront:lbl];
[imageView setImage:img];
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
[lbl.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * nImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(nImg, nil, nil, nil);
Try the code below. It works for me.
UIGraphicsBeginImageContext(imageView.bounds.size);
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *bitmap = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
P.S. I think you don't need to renderInContext UILabel layer.

Resources