Objective-C
iOS
Text on Image
Image Editing
Programming Tutorial

How to write text on image in Objective-C iOS?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Writing text onto an image in iOS is just a drawing operation: create a graphics context, draw the original image, draw the string on top, then extract a new UIImage. This pattern is used for watermarks, captions, stickers, and generated share images.

In Objective-C, the safest approach is to use a UIKit image context with explicit font and color attributes. That keeps the result sharp on Retina displays and easy to position.

Basic Approach

The flow is straightforward:

  1. start an image context sized to the original image
  2. draw the base image into that context
  3. draw the text in the desired rectangle
  4. read the final image from the context

Here is a reusable Objective-C method:

objective-c
1- (UIImage *)imageByDrawingText:(NSString *)text
2                        onImage:(UIImage *)image
3                          point:(CGPoint)point
4{
5    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
6
7    [image drawAtPoint:CGPointZero];
8
9    NSDictionary *attributes = @{
10        NSFontAttributeName: [UIFont boldSystemFontOfSize:28.0],
11        NSForegroundColorAttributeName: [UIColor whiteColor]
12    };
13
14    [text drawAtPoint:point withAttributes:attributes];
15
16    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
17    UIGraphicsEndImageContext();
18
19    return result;
20}

That method returns a new image. It does not mutate the original one.

Why UIGraphicsBeginImageContextWithOptions Matters

Using UIGraphicsBeginImageContext without the scale parameter can make text look blurry on high-density screens. The WithOptions variant lets you preserve the image scale.

These arguments matter:

  • first argument is the canvas size
  • second argument controls opacity
  • third argument is the scale, and using image.scale or 0.0 keeps Retina rendering sharp

For example:

objective-c
UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);

If you pass 1.0 on a Retina image, the text may look soft because the generated bitmap has fewer pixels than the source image.

Centering and Wrapping Text

For a watermark or caption, drawAtPoint: is sometimes too primitive. A rectangle-based draw call is better when you need centering, alignment, or multiple lines.

objective-c
1- (UIImage *)imageByDrawingCaption:(NSString *)caption onImage:(UIImage *)image
2{
3    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
4    [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
5
6    NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
7    style.alignment = NSTextAlignmentCenter;
8    style.lineBreakMode = NSLineBreakByWordWrapping;
9
10    NSDictionary *attributes = @{
11        NSFontAttributeName: [UIFont systemFontOfSize:24.0 weight:UIFontWeightSemibold],
12        NSForegroundColorAttributeName: [UIColor whiteColor],
13        NSParagraphStyleAttributeName: style
14    };
15
16    CGRect textRect = CGRectMake(20, image.size.height - 120,
17                                 image.size.width - 40, 100);
18    [caption drawInRect:textRect withAttributes:attributes];
19
20    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
21    UIGraphicsEndImageContext();
22    return result;
23}

This version is better for captions because it gives the text room to wrap instead of clipping after the first line.

Improving Readability

White text over a bright photo can disappear. A small shadow or translucent background rectangle usually makes the result much more readable.

Here is one simple shadow-based version:

objective-c
1NSShadow *shadow = [[NSShadow alloc] init];
2shadow.shadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
3shadow.shadowBlurRadius = 4.0;
4shadow.shadowOffset = CGSizeMake(0, 1);
5
6NSDictionary *attributes = @{
7    NSFontAttributeName: [UIFont boldSystemFontOfSize:28.0],
8    NSForegroundColorAttributeName: [UIColor whiteColor],
9    NSShadowAttributeName: shadow
10};

If you need a stronger effect, draw a semi-transparent rectangle before drawing the text:

objective-c
[[[UIColor blackColor] colorWithAlphaComponent:0.35] setFill];
UIRectFill(CGRectMake(0, image.size.height - 90, image.size.width, 90));

That is a good choice for share cards where the image background can vary dramatically.

Using the Result in a View

Once you have the new image, you can assign it to an image view or write it to disk:

objective-c
1UIImage *composited = [self imageByDrawingText:@"Hello iOS"
2                                       onImage:sourceImage
3                                         point:CGPointMake(24, 24)];
4
5self.imageView.image = composited;

Or save it:

objective-c
NSData *pngData = UIImagePNGRepresentation(composited);
[pngData writeToFile:path atomically:YES];

If you are processing large images or many images in a row, do the rendering work off the main thread and only update UIKit views on the main thread afterward.

Common Pitfalls

The most common problem is blurry output from using the wrong scale. Always use UIGraphicsBeginImageContextWithOptions with the original image scale or 0.0.

Another frequent mistake is forgetting that image coordinates are in points, not raw pixels. If the text looks misplaced, check whether you are mixing image size, view size, and image scale.

People also often use drawAtPoint: for long text. That works for short labels but does not wrap or align content. Use drawInRect:withAttributes: when you need layout.

Finally, avoid doing repeated large-image composition on the main thread in scrollable interfaces. Rendering is fast for one image, but a whole list of them can still cause dropped frames.

Summary

  • Draw text on an image by creating a graphics context, drawing the image, then drawing the string.
  • Use UIGraphicsBeginImageContextWithOptions so the result stays sharp on Retina screens.
  • 'drawAtPoint: is fine for short labels, while drawInRect:withAttributes: is better for captions.'
  • Text attributes such as font, color, paragraph style, and shadow make the output readable.
  • The result is a new UIImage that you can display or save.
  • For large or repeated processing, move composition work off the main thread.

Course illustration
Course illustration

All Rights Reserved.