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.