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

IosIphoneUiimageview

Ios Problem Overview


I want to make an image like this programmatically:

example

I have the upper image and text with me. Should I write text on the image?

I want to make it a complete .png image(image + label) and set it as the background of the button.

Ios Solutions


Solution 1 - Ios

Draw text inside an image and return the resulting image:

+(UIImage*) drawText:(NSString*) text 
             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];
    [text drawInRect:CGRectIntegral(rect) withFont:font]; 
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

Usage:

// note: replace "ImageUtils" with the class where you pasted the method above
UIImage *img = [ImageUtils drawText:@"Some text"                            inImage:img                             atPoint:CGPointMake(0, 0)];

Change the origin of the text inside the image from 0,0 to whatever point you like.

To paint a rectangle of solid color behind the text, add the following before the line [[UIColor whiteColor] set];:

[[UIColor brownColor] set];
CGContextFillRect(UIGraphicsGetCurrentContext(), 
                  CGRectMake(0, (image.size.height-[text sizeWithFont:font].height), 
                                  image.size.width, image.size.height));

I'm using the text size to calculate the origin for the solid color rectangle, but you can replace it with any number.

Solution 2 - Ios

My contribution to the first answer with iOS 7 support :

+(UIImage*) drawText:(NSString*) text
             inImage:(UIImage*)  image
             atPoint:(CGPoint)   point
{
    UIGraphicsBeginImageContextWithOptions(image.size, YES, 0.0f);
    [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];
    
    UIFont *font = [UIFont boldSystemFontOfSize:12];
    if([text respondsToSelector:@selector(drawInRect:withAttributes:)])
    {
        //iOS 7
        NSDictionary *att = @{NSFontAttributeName:font};
        [text drawInRect:rect withAttributes:att];
    }
    else
    {
        //legacy support
        [text drawInRect:CGRectIntegral(rect) withFont:font];
    }
    
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

Hope this helps

EDIT: modified the UIGraphicsBeginImageContextWithOptions to handle screen scale. Thk @SoftDesigner

Solution 3 - Ios

Here is the Swift version.

func textToImage(drawText: NSString, inImage: UIImage, atPoint:CGPoint)->UIImage{
    
    // Setup the font specific variables
    var textColor: UIColor = UIColor.whiteColor()
    var textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)!

    //Setup the image context using the passed image.
    UIGraphicsBeginImageContext(inImage.size)
    
    //Setups up the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
    ]
    
    //Put the image into a rectangle as large as the original image.
    inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))

    // Creating a point within the space that is as bit as the image.
    var rect: CGRect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height)

    //Now Draw the text into an image.
    drawText.drawInRect(rect, withAttributes: textFontAttributes)
    
    // Create a new image out of the images we have created
    var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    
    // End the context now that we have the image we need
    UIGraphicsEndImageContext()
    
    //And pass it back up to the caller.
    return newImage
    
}

To call it you just pass in an image.

textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))

The following links helped me get this straight.

https://stackoverflow.com/questions/26201844/swift-drawing-text-with-drawinrectwithattributes

https://stackoverflow.com/questions/6992830/how-to-write-text-on-image-in-objective-c-iphone

The original goal was to create a dynamic image that I could use in an AnnotaionView such as putting a price at a given location on a map and this worked out great for it. Hope this helps someone trying to do the same thing.

Solution 4 - Ios

iOS7 only.

Watermark in lower right corner.

@interface UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text;
@end
@implementation UIImage (DrawWatermarkText)
-(UIImage*)drawWatermarkText:(NSString*)text {
	UIColor *textColor = [UIColor colorWithWhite:0.5 alpha:1.0];
	UIFont *font = [UIFont systemFontOfSize:50];
	CGFloat paddingX = 20.f;
	CGFloat paddingY = 20.f;
	
	// Compute rect to draw the text inside
	CGSize imageSize = self.size;
	NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
	CGSize textSize = [text sizeWithAttributes:attr];
	CGRect textRect = CGRectMake(imageSize.width - textSize.width - paddingX, imageSize.height - textSize.height - paddingY, textSize.width, textSize.height);
	
    // Create the image
	UIGraphicsBeginImageContext(imageSize);
    [self drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
	[text drawInRect:CGRectIntegral(textRect) withAttributes:attr];
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultImage;
}
@end

Usage:

UIImage *image = [UIImage imageNamed:@"mona_lisa"];
image = [image drawWatermarkText:@"Leonardo da Vinci"];

Solution 5 - Ios

I did something like this! After browsing and combining some examples.

Puts the text in the midle of the image, resizing the font if needed.

UIImage *myImage = [UIImage imageNamed:@"promoicon.png"];
UIGraphicsBeginImageContext(myImage.size);
[myImage drawInRect:CGRectMake(0,0,myImage.size.width,myImage.size.height)];
UITextView *myText = [[UITextView alloc] init];
myText.font = [UIFont fontWithName:@"TrebuchetMS-Bold" size:15.0f];
myText.textColor = [UIColor whiteColor];
myText.text = NSLocalizedString(@"promotionImageText", @"");
myText.backgroundColor = [UIColor clearColor];
    
CGSize maximumLabelSize = CGSizeMake(myImage.size.width,myImage.size.height);
CGSize expectedLabelSize = [myText.text sizeWithFont:myText.font                     
                                          constrainedToSize:maximumLabelSize 
                                              lineBreakMode:UILineBreakModeWordWrap];
    
myText.frame = CGRectMake((myImage.size.width / 2) - (expectedLabelSize.width / 2),
                                  (myImage.size.height / 2) - (expectedLabelSize.height / 2),
                                  myImage.size.width,
                                  myImage.size.height);
        
[[UIColor whiteColor] set];
[myText.text drawInRect:myText.frame withFont:myText.font];
UIImage *myNewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Solution 6 - Ios

I have created fully customized extension for UIImage to draw watermark in Swift:

extension UIImage{
    
    enum WaterMarkCorner{
        case TopLeft
        case TopRight
        case BottomLeft
        case BottomRight
    }
    
    func waterMarkedImage(#waterMarkText:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.whiteColor(), waterMarkTextFont:UIFont = UIFont.systemFontOfSize(20), backgroundColor:UIColor = UIColor.clearColor()) -> UIImage{
        
        let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont]
        let textSize = NSString(string: waterMarkText).sizeWithAttributes(textAttributes)
        var textFrame = CGRectMake(0, 0, textSize.width, textSize.height)
        
        let imageSize = self.size
        switch corner{
        case .TopLeft:
            textFrame.origin = margin
        case .TopRight:
            textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
        case .BottomLeft:
            textFrame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
        case .BottomRight:
            textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }
        
        /// Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.drawInRect(CGRectMake(0, 0, imageSize.width, imageSize.height))
        NSString(string: waterMarkText).drawInRect(textFrame, withAttributes: textAttributes)
        
        let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return waterMarkedImage
    }
}

As you see, I have added some default values for attributes so you can ignore if you don't need to change. Here some examples for how to use it:

let watermark1 = image.waterMarkedImage(waterMarkText: "@yourapp")
    
let watermark2 = image.waterMarkedImage(waterMarkText: "your app name", corner: .TopRight, margin: CGPoint(x: 5, y: 5), waterMarkTextColor: UIColor.greenColor())
    
let watermark3 = image.waterMarkedImage(waterMarkText: "appName", waterMarkTextColor: UIColor.blackColor(), waterMarkTextFont: UIFont(name: "Helvatica", size: 25)!)

Swift 4.0 version:

extension UIImage
{
    
    enum WaterMarkCorner
    {
        case TopLeft
        case TopRight
        case BottomLeft
        case BottomRight
    }
    
    func waterMarkedImage(text:String, corner:WaterMarkCorner = .BottomRight, margin:CGPoint = CGPoint(x: 20, y: 20), color:UIColor = UIColor.white, font:UIFont = UIFont.systemFont(ofSize: 20), background:UIColor = UIColor.clear) -> UIImage?
    {
        let attributes = [NSAttributedStringKey.foregroundColor: color, NSAttributedStringKey.font:font]
        let textSize = NSString(string: text).size(withAttributes: attributes)
        var frame = CGRect(x: 0, y: 0, width: textSize.width, height: textSize.height)
        
        let imageSize = self.size
        switch corner
        {
            case .TopLeft:
                frame.origin = margin
            case .TopRight:
                frame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
            case .BottomLeft:
                frame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
            case .BottomRight:
                frame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }
        
        // Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.draw(in: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
        NSString(string: text).draw(in: frame, withAttributes: attributes)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
}

Solution 7 - Ios

Here is a Swift version which correctly centers the text on the image. This works with text of various sizes.

func addTextToImage(text: NSString, inImage: UIImage, atPoint:CGPoint)     -> UIImage{
    
    // Setup the font specific variables
    let textColor = YOURCOLOR
    let textFont = YOUR SIZE
    
    //Setups up the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
    ]
    
    // Create bitmap based graphics context
    UIGraphicsBeginImageContextWithOptions(inImage.size, false, 0.0)

    //Put the image into a rectangle as large as the original image.
    inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))
    
    // Our drawing bounds
    let drawingBounds = CGRectMake(0.0, 0.0, inImage.size.width, inImage.size.height)
    
    let textSize = text.sizeWithAttributes([NSFontAttributeName:textFont])
    let textRect = CGRectMake(drawingBounds.size.width/2 - textSize.width/2, drawingBounds.size.height/2 - textSize.height/2,
        textSize.width, textSize.height)
    
    text.drawInRect(textRect, withAttributes: textFontAttributes)
    
    // Get the image from the graphics context
    let newImag = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    
    return newImag

}

Solution 8 - Ios

Use this method to add your textfield on image with selected font and color and size

//Method to add 
- (UIImage *) addText:(UIImage *)img text:(NSString *)text
{
    CGRect rect =  CGRectMake(0,0, img.size.width, img.size.height);

    // create a context according to image size
    UIGraphicsBeginImageContext(rect.size);

    // draw image
    [img drawInRect:rect];

 
    float fontSize = _txtvwEdit.font.pointSize*2;
    NSLog(@"Original %f new %f",_txtvwEdit.font.pointSize,fontSize);

    UIFont* font = [UIFont fontWithName:_txtvwEdit.font.fontName size:fontSize];

    CGRect textRect = CGRectMake((_txtvwEdit.frame.origin.x*2)-5,_txtvwEdit.frame.origin.y*2,_txtvwEdit.frame.size.width*2,_txtvwEdit.frame.size.height*2);

    if ([temparyGifframes count]>0)
    {
        font = [UIFont fontWithName:_txtvwEdit.font.fontName size:_txtvwEdit.font.pointSize];
    
        textRect =    CGRectMake(_txtvwEdit.frame.origin.x,_txtvwEdit.frame.origin.y ,_txtvwEdit.frame.size.width,_txtvwEdit.frame.size.height);

    }

    /// Make a copy of the default paragraph style
    NSMutableParagraphStyle* paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
    paragraphStyle.alignment = NSTextAlignmentLeft;

    NSDictionary *attributes = @{ NSFontAttributeName: font, NSForegroundColorAttributeName: _txtvwEdit.textColor,NSParagraphStyleAttributeName: paragraphStyle };

    // draw text
    [text drawInRect:textRect withAttributes:attributes];


    // get as image
    UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image; 
}

Solution 9 - Ios

Considering performance, you should avoid having frequent calls to -drawRect:. Every UIView is backed with a CALayer and images as layer contents remain in memory as long as the CALayer stays in the hierarchy.This means that most of the operations you see in an application, including movement, rotation, and scaling of the view/layer, do not require a redraw.This means you can use add an CATextLayer on UIImageView , If you don't need a image with watermark. https://developer.apple.com/library/ios/qa/qa1708/_index.html

    CATextLayer *textLayer = [CATextLayer layer];
    UIFont *font = [UIFont systemFontOfSize:14.0f];
    CGSize textSize = [text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:14.0f]}];
    textLayer.frame = CGRectMake((imageView.size.width - textSize.width)/2,
                                 (imageView.size.height - textSize.height)/2,
                                 textSize.width, textSize.height);;
    textLayer.string = text;
    textLayer.fontSize = font.pointSize;
    [imageView.layer addSublayer:textLayer];
}

Solution 10 - Ios

In Swift-3 of @Jano Answer :-

func drawText(text:NSString ,image:UIImage ,point:CGPoint ) -> UIImage {
        
        let font = UIFont.boldSystemFont(ofSize: 12)
        UIGraphicsBeginImageContext(image.size)
        image.draw(in:CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) )
            let rect = CGRect(x: point.x, y: point.y, width:image.size.width, height: image.size.height )
        UIColor.white.set()
        text.draw(in: rect.integral, withAttributes: [NSFontAttributeName   : font])
        let image =  UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    

Solution 11 - Ios

Swift 3

extension UIImage {
    
    func textToImage(drawText: NSString, atPoint:CGPoint) -> UIImage? {
        
        // Setup the font specific variables
        let textColor: UIColor = UIColor.white
        let textFont: UIFont = UIFont(name: "Helvetica Bold", size: 12)!
        
        //Setup the image context using the passed image.
        UIGraphicsBeginImageContext(self.size)
        
        //Setups up the font attributes that will be later used to dictate how the text should be drawn
        let textFontAttributes = [
            NSFontAttributeName: textFont,
            NSForegroundColorAttributeName: textColor,
            ] as [String : Any]
        
        //Put the image into a rectangle as large as the original image.
        self.draw(in: CGRect(x:0, y:0, width:self.size.width, height: self.size.height))
        
        // Creating a point within the space that is as bit as the image.
        let rect: CGRect = CGRect(x:atPoint.x, y:atPoint.y, width:self.size.width, height:self.size.height)
        
        //Now Draw the text into an image.
        drawText.draw(in: rect, withAttributes: textFontAttributes)
        
        // Create a new image out of the images we have created
        let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
        
        // End the context now that we have the image we need
        UIGraphicsEndImageContext()
        
        //And pass it back up to the caller.
        return newImage
        
    }
}

Solution 12 - Ios

Swift 3 version of @Hossam Ghareebs answer and added the missing integration of the backgroundColor parameter:

enum WaterMarkCorner{
    case TopLeft
    case TopRight
    case BottomLeft
    case BottomRight
}

extension UIImage{
        
    func waterMarkedImage(_ waterMarkText:String, corner:WaterMarkCorner = .TopRight, margin:CGPoint = CGPoint(x: 20, y: 20), waterMarkTextColor:UIColor = UIColor.black, waterMarkTextFont:UIFont = UIFont.systemFont(ofSize: 40), backgroundColor:UIColor = UIColor(white: 1.0, alpha: 0.5)) -> UIImage?{
        
        let textAttributes = [NSForegroundColorAttributeName:waterMarkTextColor, NSFontAttributeName:waterMarkTextFont, NSBackgroundColorAttributeName: backgroundColor]
        let textSize = NSString(string: waterMarkText).size(attributes: textAttributes)
        var textFrame = CGRect(x:0, y:0, width:textSize.width, height:textSize.height)
        
        let imageSize = self.size
        switch corner{
        case .TopLeft:
            textFrame.origin = margin
        case .TopRight:
            textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: margin.y)
        case .BottomLeft:
            textFrame.origin = CGPoint(x: margin.x, y: imageSize.height - textSize.height - margin.y)
        case .BottomRight:
            textFrame.origin = CGPoint(x: imageSize.width - textSize.width - margin.x, y: imageSize.height - textSize.height - margin.y)
        }
        
        /// Start creating the image with water mark
        UIGraphicsBeginImageContext(imageSize)
        self.draw(in: CGRect(x:0, y:0, width:imageSize.width, height:imageSize.height))
        
        NSString(string: waterMarkText).draw(in: textFrame, withAttributes: textAttributes)
        
        let waterMarkedImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return waterMarkedImage
    }
}

Solution 13 - Ios

My function can add text water mark on image with 45 degree and 90 degree rotations

+(UIImage *)drawText:(NSString *)text diagonallyOnImage:(UIImage *)image rotation:(WatermarkRotation)rotation{
    
    UIColor *textColor = [UIColor colorWithRed:255 green:0 blue:0 alpha:0.2];//[UIColor colorWithWhite:0.5 alpha:1.0];
    UIFont *font = [UIFont systemFontOfSize:250];

    // Compute rect to draw the text inside
    NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
    CGSize textSize = [text sizeWithAttributes:attr];
    CGSize imageSize = image.size;
    // Create a bitmap context into which the text will be rendered.
    UIGraphicsBeginImageContext(textSize);
    // Render the text
    [text drawAtPoint:CGPointMake(0,0) withAttributes:attr];
    // Retrieve the image
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
    
    CGImageRef imageRef = [img CGImage];
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    
    
    CGContextRef bitmap = CGBitmapContextCreate(NULL, textSize.width, textSize.width, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
    switch (rotation) {
        case WatermarkRotation90left:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(-90));
            CGContextTranslateCTM(bitmap, -textSize.width, 0);
            break;
        
        case WatermarkRotation90right:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(90));
            CGContextTranslateCTM(bitmap, 0, -textSize.width);
            break;
            
        case WatermarkRotation45ltr:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(45));
            CGContextTranslateCTM(bitmap, textSize.width/4, -textSize.width/2);
            break;
        
        case WatermarkRotation45rtl:
            CGContextRotateCTM (bitmap, DEGREES_RADIANS(-45));
            CGContextTranslateCTM(bitmap, -textSize.width/2, textSize.width/4);
            break;
            
        default:
            break;
    }
    
    CGContextDrawImage(bitmap, CGRectMake(0, (textSize.width/2)-(textSize.height/2), textSize.width, textSize.height), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];
    
    UIGraphicsBeginImageContext( imageSize );
    
    // Use existing opacity as is
    [image drawInRect:CGRectMake(0,0,imageSize.width,imageSize.height)];
    
    
    if (rotation == WatermarkRotation90left) {
        [newImage drawInRect:CGRectMake(-((textSize.width/2)-(textSize.height/2)),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }else if(rotation == WatermarkRotation90right){
        [newImage drawInRect:CGRectMake((imageSize.width-textSize.width/2)-(textSize.height/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }else{
        [newImage drawInRect:CGRectMake((imageSize.width/2)-(textSize.width/2),(imageSize.height/2)-(textSize.width/2),textSize.width,textSize.width) blendMode:kCGBlendModeNormal alpha:1.0];
    }
    
    
    UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext();
    
    
    UIGraphicsEndImageContext();
    return mergedImage;
}

Enum for rotation:

typedef enum:NSUInteger{
    WatermarkRotation90left=1,
    WatermarkRotation90right,
    WatermarkRotation45ltr,
    WatermarkRotation45rtl
}WatermarkRotation;

Note: Use 0 for drawing watermark in centre of image.(Default case of switch statement)

Add this macro for degree to radian:

#define DEGREES_RADIANS(angle) ((angle) / 180.0 * M_PI)

Hope this helps !!!

Solution 14 - Ios

I built a solution based on the example provided by @harish-pathak. It takes devices with HiDPI-displays into consideration (size is int, whereas left and top are percent as double).

-(UIImage *)drawText:(NSString *)text onImage:(UIImage *)image withSize:(NSInteger)size posLeft:(double)left posTop:(double)top {
    
    // Get UI scale for HiDPI
    CGFloat scale = [[UIScreen mainScreen] scale];
    
    UIColor *textColor = [UIColor whiteColor];
    UIFont *font = [UIFont fontWithName:@"Font-Name" size:size];
    
    // Compute rect to draw the text inside
    NSDictionary *attr = @{NSForegroundColorAttributeName: textColor, NSFontAttributeName: font};
    CGSize textSize = [text sizeWithAttributes:attr];
    CGSize imageSize = image.size;
    
    // Create a bitmap context into which the text will be rendered
    UIGraphicsBeginImageContextWithOptions(textSize, NO, scale);
    
    // Render the text
    [text drawAtPoint:CGPointMake(0,0) withAttributes:attr];
    // Retrieve the image
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();

    CGImageRef imageRef = [img CGImage];
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    
    // Create bitmap context for text
    CGFloat scaledTextWidth = textSize.width * scale;
    CGFloat scaledTextHeight = textSize.height * scale;
    CGContextRef textBitmap = CGBitmapContextCreate(NULL, scaledTextWidth, scaledTextHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
    // Scale text for HiDPI devices
    CGContextScaleCTM(textBitmap, scale, scale);
    
    // Draw image for text
    CGRect textPosition = CGRectMake(0, 0, textSize.width, textSize.height);
    CGRect textPixelAligned = CGRectIntegral(textPosition);
    CGContextDrawImage(textBitmap, textPixelAligned, imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(textBitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];
    
    // Create bitmap context into which the image will be rendered
    UIGraphicsBeginImageContextWithOptions(imageSize, NO, scale);

    // Use existing opacity as is
    [image drawInRect:CGRectMake(0,0,imageSize.width,imageSize.height)];
    
    // Create new image with blendmode "normal"
    CGFloat textLeft = (imageSize.width*left)-(textSize.width*0.5);
    CGFloat textTop = (imageSize.height*top)-(textSize.height*0.5);
    CGRect imagePosition = CGRectMake(textLeft,textTop,textSize.width,textSize.height);
    CGRect imagePixelAligned = CGRectIntegral(imagePosition);
    [newImage drawInRect:imagePixelAligned blendMode:kCGBlendModeNormal alpha:1.0];
    
    // Get merged image from context
    UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();
    return mergedImage;
}

To center text on image call the function like this:

[self drawText:@"Text" onImage:img withSize:120 posLeft:0.5 posTop:0.5];

Credits to:

Solution 15 - Ios

UIImageView *imageView = [UIImageView alloc];
imageView.image = [UIImage imageNamed:@"img.png"];
UILabel *label = [UILabel alloc];
label.text = @"Your text";
[imageView addsubview:label];

Set the frame of the label where you want the label to be displayed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSanchit PaurushView Question on Stackoverflow
Solution 1 - IosJanoView Answer on Stackoverflow
Solution 2 - IosiGranDavView Answer on Stackoverflow
Solution 3 - IosChristopher Wade CantleyView Answer on Stackoverflow
Solution 4 - IosneoneyeView Answer on Stackoverflow
Solution 5 - IosnunoinesView Answer on Stackoverflow
Solution 6 - IosHossam GhareebView Answer on Stackoverflow
Solution 7 - IossuperpeteblazeView Answer on Stackoverflow
Solution 8 - IosPiyushkumarView Answer on Stackoverflow
Solution 9 - IosRY_ ZhengView Answer on Stackoverflow
Solution 10 - IosShrawanView Answer on Stackoverflow
Solution 11 - IosjohnnyMacView Answer on Stackoverflow
Solution 12 - IosWerner KratochwilView Answer on Stackoverflow
Solution 13 - IosHarish PathakView Answer on Stackoverflow
Solution 14 - IosRafa2602View Answer on Stackoverflow
Solution 15 - IosPraveen SView Answer on Stackoverflow