Как использовать функциональность рисования NSString для создания UIImage из текста - PullRequest
36 голосов
/ 04 мая 2010

Я хотел бы нарисовать содержимое переменной NSString в UIImage, но я абсолютно не знаю, как это сделать. Мне нужно написать метод, который получит NSString в качестве параметра и вернет UIImage с текстом, нарисованным в нем.

Ответы [ 4 ]

88 голосов
/ 04 мая 2010

Вы можете попробовать это: (обновлено для iOS 4)

-(UIImage *)imageFromText:(NSString *)text
{
    // set the font type and size
    UIFont *font = [UIFont systemFontOfSize:20.0];  
    CGSize size  = [text sizeWithFont:font];

    // check if UIGraphicsBeginImageContextWithOptions is available (iOS is 4.0+)
    if (UIGraphicsBeginImageContextWithOptions != NULL)
        UIGraphicsBeginImageContextWithOptions(size,NO,0.0);
    else
        // iOS is < 4.0 
        UIGraphicsBeginImageContext(size);

    // optional: add a shadow, to avoid clipping the shadow you should make the context size bigger 
    //
    // CGContextRef ctx = UIGraphicsGetCurrentContext();
    // CGContextSetShadowWithColor(ctx, CGSizeMake(1.0, 1.0), 5.0, [[UIColor grayColor] CGColor]);

    // draw in context, you can use also drawInRect:withFont:
    [text drawAtPoint:CGPointMake(0.0, 0.0) withFont:font];

    // transfer image
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();    

    return image;
}

Чтобы назвать это:

UIImage *image = [self imageFromText:@"This is a text"];
14 голосов
/ 31 декабря 2014

Добавление версии Swift, также дает вам больше возможностей:

class func sizeOfAttributeString(str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
    let size = str.boundingRectWithSize(CGSizeMake(maxWidth, 1000), options:(NSStringDrawingOptions.UsesLineFragmentOrigin), context:nil).size
    return size
}

class func imageFromText(text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage {
    let paragraph = NSMutableParagraphStyle()
    paragraph.lineBreakMode = NSLineBreakMode.ByWordWrapping
    paragraph.alignment = .Center // potentially this can be an input param too, but i guess in most use cases we want center align

    let attributedString = NSAttributedString(string: text, attributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color, NSParagraphStyleAttributeName:paragraph])

    let size = sizeOfAttributeString(attributedString, maxWidth: maxWidth)
    UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
    attributedString.drawInRect(CGRectMake(0, 0, size.width, size.height))
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}
2 голосов
/ 04 мая 2010

Начните контекст изображения с UIGraphicsBeginImageContext, нарисуйте его, получите изображение с UIGraphicsGetImageFromCurrentImageContext, завершите его UIGraphicsEndImageContext

1 голос
/ 07 июня 2017

Swift 3.1

func sizeOfAttributeString(str: NSAttributedString, maxWidth: CGFloat) -> CGSize {
    let size = str.boundingRect(with: CGSize(width: maxWidth, height: 1000), options:(NSStringDrawingOptions.usesLineFragmentOrigin), context:nil).size
    return size
}

func imageFromText(text:NSString, font:UIFont, maxWidth:CGFloat, color:UIColor) -> UIImage {
    let paragraph = NSMutableParagraphStyle()
    paragraph.lineBreakMode = NSLineBreakMode.byWordWrapping
    paragraph.alignment = .center 

    let attributedString = NSAttributedString(string: text as String, attributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color, NSParagraphStyleAttributeName:paragraph])

    let size = sizeOfAttributeString(str: attributedString, maxWidth: maxWidth)
    UIGraphicsBeginImageContextWithOptions(size, false , 0.0)
    attributedString.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image!
}

Благодарность идет за Бао Лея за прекрасный ответ.

...