如何在iOS上将文本转换为图像?

25

我正在试图编写一个将文本字段文本转换为图像的函数(示例)。我已经尝试搜索样例,大部分样例也是在图像上覆盖文本。是否可能给我一些示例或提示如何做到这一点?


我需要这个功能是因为我从服务器获取数据。如果数据中有图片,则UIIMAGEView将显示该图片,但如果没有图片,则我需要将内容的一部分转换成图片并在UIIMAGEVIEW上显示。 - Lazarus
请查看我在此处提供的解决方案。Swift 3 :将文本转换为UIImage iOS - Ankit Kumar Gupta
请参考我的Swift 4 / iOS 11答案,该答案展示了将文本转换为图像(或视图)的6种不同方法,以便显示它。链接:https://dev59.com/bnI-5IYBdhLWcg3w3cnS#45821857 - Imanou Petit
7个回答

54

有几种可能的方法。

  1. 如果您已经有一个现有的UITextFieldUITextView或者UILabel,想要将其渲染成图像,那么您可以采用传统的快照方法,例如:

- (UIImage *)imageForView:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0);

    if ([view respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])
        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];  // if we have efficient iOS 7 method, use it ...
    else
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];         // ... otherwise, fall back to tried and true methods

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

    return image;
}
  • 如果您想要一个通用的“从文本创建图像”的例程,在iOS 7中,它看起来像:

  • - (UIImage *)imageFromString:(NSString *)string attributes:(NSDictionary *)attributes size:(CGSize)size
    {
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
        [string drawInRect:CGRectMake(0, 0, size.width, size.height) withAttributes:attributes];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    以上代码将创建一个大小基于文本的图像。如果你只想要一个固定大小的图像,那么使用常量frame而不是动态构建它。

    无论如何,你可以按照以下方式使用上述代码:

    NSString *string = @"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
    
    NSDictionary *attributes = @{NSFontAttributeName            : [UIFont systemFontOfSize:20],
                                 NSForegroundColorAttributeName : [UIColor blueColor],
                                 NSBackgroundColorAttributeName : [UIColor clearColor]};
    
    UIImage *image = [self imageFromString:string attributes:attributes size:self.imageView.bounds.size];
    
  • 如果你需要支持早期的 iOS 版本,你可以使用这种技术:

  • - (UIImage *)imageFromString:(NSString *)string font:(UIFont *)font size:(CGSize)size
    {
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
        [string drawInRect:CGRectMake(0, 0, size.width, size.height) withFont:font lineBreakMode: NSLineBreakByWordWrapping];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    这些都有很多变化,具体取决于你想要实现什么。


    另一种方法是在视图中同时使用UIImageViewUILabel/UITextView对象,如果你从服务器获得了一张图片,就设置UIImageView的图像,如果有文本,则设置UILabel/UITextViewtext属性。


    好答案! 如果您需要将彩色文本转换为可着色的图像,例如UIBarButtonItem,您有两个选项: 1)为项目设置色调颜色,例如:[buttonItem setTintColor:color]; 2)在返回uiimage之前指定渲染模式,例如:return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; - Andreas K
    @Rob 虽然这是一个非常老的答案...但我想要实现你回答中的第三个选项。但它将文本放置在左对齐。我怎样才能使它居中对齐?我只想要图像中的两个字母。 - Jay Pandya
    为什么不选择第二个选项呢?在那种情况下,你可以参考https://dev59.com/mnRB5IYBdhLWcg3w4bKv#477658。如果你不这样做,你就必须手动计算一行文本所占的边界矩形,然后通过正确的量来偏移你绘制它的`origin`。第二个选项要简单得多。 - Rob

    9
    NSString *string = @"Some text";
    UIGraphicsBeginImageContext(CGSizeMake(80, 50));
    [string drawAtPoint:CGPointMake(10, 20)
               withFont:[UIFont systemFontOfSize:12]];
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    

    您可以从这里开始


    5

    快速回答

    如果您只需要获取UIFieldViewUITextViewUILabel的可见内容图像,则可以使用以下方法。

    func imageFromView(myView: UIView) -> UIImage {
    
        UIGraphicsBeginImageContextWithOptions(myView.bounds.size, false, UIScreen.mainScreen().scale)
        myView.drawViewHierarchyInRect(myView.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
    

    特殊情况

    当文本内容滚出框架时,比如在UITextView中,上面的解决方案只会捕捉到可见区域。为了获取所有内容,一种解决方案是先将文本视图的副本大小调整为其内容视图的大小,然后再制作其图像。

    func imageFromTextView(textView: UITextView) -> UIImage {
    
        // Make a copy of the textView first so that it can be resized 
        // without affecting the original.
        let textViewCopy = UITextView(frame: textView.frame)
        textViewCopy.attributedText = textView.attributedText
        
        // resize if the contentView is larger than the frame
        if textViewCopy.contentSize.height > textViewCopy.frame.height {
            textViewCopy.frame = CGRect(origin: CGPointZero, size: textViewCopy.contentSize)
        }
        
        // draw the text view to an image
        UIGraphicsBeginImageContextWithOptions(textViewCopy.bounds.size, false, UIScreen.mainScreen().scale)
        textViewCopy.drawViewHierarchyInRect(textViewCopy.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
    

    注意事项

    • 您也可以简单地调整原始文本视图的大小,然后再将其调整回来。但是,制作临时副本似乎更简单。
    • 获取视图副本的另一种方法是对其进行归档和取消归档
    • 或者,您可以直接写入UIImage中。

    这真是太有帮助了。感谢您的分享。 - Ivan Cantarino

    3
    你可以尝试创建自己的自定义UIView子类,将NSString(你的文本)绘制在上面,然后将其转换为UIImage。你只能在-drawRect:方法中在UIView上绘制文本。以下是你的子类的一个想法。
    @interface TextView : UIView {
        NSString *_text;
    }
    - (id)initWithFrame:(CGRect)frame andText:(NSString *)text;
    @end
    
    @implementation TextView
    - (id)initWithFrame:(CGRect)frame andText:(NSString *)text
    {
        if (self = [super initWithFrame:frame]) {
            _text = text;
        }
        [self setNeedsDisplay]; // calls the -drawRect method
        return self;
    }
    
    - (void)drawRect:(CGRect)rect
    {
        [_text drawAtPoint:/* location of text*/ 
            withAttributes:/* style    of text*/];
    }
    

    关于绘制 NSString 的更多信息可以在这里找到 一旦您拥有了带有文本的视图,请使用此技术将其转换为 UIImage


    1
    很简单。您想将文本转换为UIImage。只需将文本视图的层绘制到图像上下文中并转换为UIImage即可。代码如下。
    + (UIImage *) imageWithView:(UITextView *)view
    {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    
        UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return img;
    }
    

    1
    这是一个居中对齐的版本。
    - (UIImage *)imageFromString:(NSString *)string size:(CGSize)size
    {
        NSDictionary *attributes = @{NSFontAttributeName            : [UIFont systemFontOfSize:18],
                                     NSForegroundColorAttributeName : [UIColor whiteColor],
                                     NSBackgroundColorAttributeName : [UIColor redColor]
                                     };    
    
        UIGraphicsBeginImageContext(size);
        CGRect txtRect = [string boundingRectWithSize:CGSizeZero
                                           options:NSStringDrawingUsesLineFragmentOrigin
                                        attributes:attributes
                                           context:nil];
    
        [string drawAtPoint:CGPointMake(size.width/2 - txtRect.size.width/2, size.height/2 - txtRect.size.height/2) withAttributes:attributes];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    使用方法如下:
    NSString *string = @"A";
    
    UIImage *image = [self imageFromString:string size:imgView.bounds.size];
    [imgView.bounds setImage:image];
    [imgView.bounds setBackgroundColor:[UIColor redColor];//Full margin with same color of text image color.
    

    0
    NSString * ImgString = [[[self.dataDict valueForKey:@"newsItems"]objectAtIndex:indexPath.row]valueForKey:@"image"];
    
    NSURL *imageURL = [NSURL URLWithString:ImgString];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    
    cell.imageLabel.image = image;
    

    我想在表格视图中展示数据,所以我正在编写这段代码在“cell for row at index path”方法中。
    (dataDict是我的字典,其中包含了所有的数据)。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接