How to convert Text to Image in Cocoa Objective-C

cocoa, objective-c

Solution

EDIT: I misread the question and assumed you wanted Cocoa-touch code (I've left it at the end in case you did). Here is one way of doing it in Cocoa using CoreText (as another poster says there are a bunch of ways):

{
    NSString* string = @"Kevin";
    CGFloat fontSize = 12.0f;

    // Create an attributed string with string and font information
    CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica Light"), fontSize, nil);
    NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                (id)font, kCTFontAttributeName, 
                                nil];
    NSAttributedString* as = [[NSAttributedString alloc] initWithString:string attributes:attributes];
    CFRelease(font);

    // Figure out how big an image we need 
    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)as);
    CGFloat ascent, descent, leading;
    double fWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

    // On iOS 4.0 and Mac OS X v10.6 you can pass null for data 
    size_t width = (size_t)ceilf(fWidth);
    size_t height = (size_t)ceilf(ascent + descent);
    void* data = malloc(width*height*4);

    // Create the context and fill it with white background
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast;
    CGContextRef ctx = CGBitmapContextCreate(data, width, height, 8, width*4, space, bitmapInfo);
    CGColorSpaceRelease(space);
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0); // white background
    CGContextFillRect(ctx, CGRectMake(0.0, 0.0, width, height));

    // Draw the text 
    CGFloat x = 0.0;
    CGFloat y = descent;
    CGContextSetTextPosition(ctx, x, y);
    CTLineDraw(line, ctx);
    CFRelease(line);

    // Save as JPEG
    CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
    NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
    NSAssert(imageRep, @"imageRep must not be nil");
    NSData* imageData = [imageRep representationUsingType:NSJPEGFileType properties:nil];
    NSString* fileName = [NSString stringWithFormat:@"Kevin.jpg"];
    NSString* fileDirectory = NSHomeDirectory();
    NSString* filePath = [fileDirectory stringByAppendingPathComponent:fileName];
    [imageData writeToFile:filePath atomically:YES];

    // Clean up
    [imageRep release];
    CGImageRelease(imageRef);
    free(data);
}

This is the cocoa-touch version:

// Figure out the dimensions of the string in a given font.
NSString* kevin = @"Kevin";
UIFont* font = [UIFont systemFontOfSize:12.0f];
CGSize size = [kevin sizeWithFont:font];
// Create a bitmap context into which the text will be rendered.
UIGraphicsBeginImageContext(size);
// Render the text 
[kevin drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];
// Retrieve the image
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
// Convert to JPEG
NSData* data = UIImageJPEGRepresentation(image, 1.0);
// Figure out a safe path
NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(
                                    NSDocumentDirectory,
                                    NSUserDomainMask,
                                    YES);
NSString *docDir = [arrayPaths objectAtIndex:0];
// Write the file
NSString *filePath = [docDir stringByAppendingPathComponent:@"Kevin.jpg"];
BOOL success = [data writeToFile:filePath atomically:YES];
if(!success)
{
    NSLog(@"Failed to write to file. Perhaps it already exists?");
}
else
{
    NSLog(@"JPEG file successfully written to %@", filePath);
}
// Clean up
UIGraphicsEndImageContext();

When I made started iOS programming I found the following things unintuitive or unusual. The methods to measure and draw strings are methods on `NSString` (not the graphics context as in other systems). The method to save the data is a method on `NSData` not a file class! The functions to create the graphics context are plain C functions and not part of any class.

Hope this helps!

Problem

I'm looking for a way to convert a piece of text to an image in Cocoa. Everything seems to describe converting an image to text not text to an image. Simply put, I would like to take a word (such as "Kevin") and convert it into a bitmap image to manipulate and save as a JPEG. The people giving answers are awesome. Thank you for three different and equally valid ways to do it(yes i've tested them)....Very cool I wish I could give you all correct answers.

Original source

Related problems