在iOS上将文本转换为图像

15
如何将文本转换为图像并显示在UIImageview中。 有人知道如何将文本转换为图像吗?
4个回答

23

使用Swift 5和iOS 12,您可以选择以下6种方式之一来解决问题。


#1. 使用NSStringdraw(at:withAttributes:)方法

在最简单的情况下,如果您想将一个带有某些属性的String转换为UIImage,您可以使用draw(at:withAttributes:)。以下Playground代码展示了如何使用draw(at:withAttributes:)String中获取一个UIImage

import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
text.draw(at: CGPoint.zero, withAttributes: attributes)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
    text.draw(at: CGPoint.zero, withAttributes: attributes)
})

PlaygroundPage.current.liveView = UIImageView(image: image)

请注意,NSAttributedString有一个类似的方法叫做draw(at:)


#2. 使用NSStringdraw(in:withAttributes:)方法

作为draw(at:withAttributes:)的替代方案,您可以使用draw(in:withAttributes:)

import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
let rect = CGRect(origin: .zero, size: textSize)
text.draw(in: rect, withAttributes: attributes)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
    let rect = CGRect(origin: .zero, size: textSize)
    text.draw(in: rect, withAttributes: attributes)
})

PlaygroundPage.current.liveView = UIImageView(image: image)

请注意,NSAttributedString 有一个类似的方法叫做 draw(in:)


#3. 使用 NSStringdraw(with:options:attributes:context:) 方法

作为 draw(at:withAttributes:)draw(in:) 的替代方案,您可以使用 draw(with:options:attributes:context:)。请注意,Apple 对于 draw(with:options:attributes:context:) 有一些建议:

此方法默认使用基准线原点。如果未指定usesLineFragmentOrigin,则将忽略矩形的高度,并认为操作是单行渲染。

import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

UIGraphicsBeginImageContextWithOptions(textSize, true, 0)
let rect = CGRect(origin: .zero, size: textSize)
text.draw(with: rect, options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport

let text = "Hello, world"
let attributes = [
    NSAttributedString.Key.foregroundColor: UIColor.yellow,
    NSAttributedString.Key.font: UIFont.systemFont(ofSize: 22)
]
let textSize = text.size(withAttributes: attributes)

let renderer = UIGraphicsImageRenderer(size: textSize)
let image = renderer.image(actions: { context in
    text.draw(with: .zero, options: [.usesLineFragmentOrigin], attributes: attributes, context: nil)
})

PlaygroundPage.current.liveView = UIImageView(image: image)

请注意,NSAttributedString 有一个类似的方法叫做 draw(with:options:context:)


#4. 使用 CALayerrender(in:) 方法

如果你想将 UILabelUITextFieldUITextView 的文本内容捕捉到 UIImage 中,可以使用 render(in:)。以下 Playground 代码显示如何使用 render(in:) 快照 UILabel 的内容文本:

import UIKit
import PlaygroundSupport

let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()

UIGraphicsBeginImageContextWithOptions(label.frame.size, true, 0)
guard let context = UIGraphicsGetCurrentContext() else { exit(0) }
label.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport

let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()

let renderer = UIGraphicsImageRenderer(size: label.frame.size)
let image = renderer.image(actions: { context in
    label.layer.render(in: context.cgContext)
})

PlaygroundPage.current.liveView = UIImageView(image: image)

#5. 使用 UIViewdrawHierarchy(in:afterScreenUpdates:) 方法

如果您想将 UILabelUITextFieldUITextView 的文本捕获为 UIImage,您可以使用 drawHierarchy(in:afterScreenUpdates:)。请注意,Apple对于 drawHierarchy(in:afterScreenUpdates:) 有一些建议:

当您想要应用图形效果(例如模糊)到视图快照时,请使用此方法。该方法不像 snapshotView(afterScreenUpdates:) 方法那样快速。

import UIKit
import PlaygroundSupport

let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()

UIGraphicsBeginImageContextWithOptions(label.frame.size, true, 0)    
_ = label.drawHierarchy(in: label.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

PlaygroundPage.current.liveView = UIImageView(image: image)
import UIKit
import PlaygroundSupport

let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()

let renderer = UIGraphicsImageRenderer(size: label.frame.size)
let image = renderer.image(actions: { context in
    _ = label.drawHierarchy(in: label.bounds, afterScreenUpdates: true)
})

PlaygroundPage.current.liveView = UIImageView(image: image)

#6. 使用 UIViewsnapshotView(afterScreenUpdates:) 方法

如果你可以通过快照操作获得一个 UIView 而不是一个 UIImage,那么你可以使用 snapshotView(afterScreenUpdates:) 方法。以下 Playground 代码展示了如何使用 snapshotView(afterScreenUpdates:) 方法将一个 UILabel 的内容文本快照到一个 UIView 中:


import UIKit
import PlaygroundSupport

let label = UILabel(frame: .zero)
label.textColor = .yellow
label.font = UIFont.systemFont(ofSize: 22)
label.text = "Hello, world"
label.sizeToFit()

let view = label.snapshotView(afterScreenUpdates: true)
PlaygroundPage.current.liveView = view

非常好的解释,谢谢帮了大忙!特别是游乐场。 - kokemomuke
1
非常好的总结!需要注意的一点是,UIGraphicsBeginImageContextWithOptions中的不透明标志(opaque flag)应该设置为false。我曾经将其设置为true,结果得到了一个黑色背景。 - Jan-Michael Tressler
@imanou 小伙伴,你有没有想过如何在iOS13中解决这个问题?https://dev59.com/Grbna4cB1Zd3GeqPje1N - Aslam

12

你可以尝试这样开始:

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

result 包含文本的 UIImage,您可以将其分配给 UIImageView 的 image 属性。


你怎么让文本变成白色? - Jack Solomon

1

SWIFT 3 :

创建一个UIImage的扩展,这样你就可以在任何地方使用它:

extension UIImage {
    class func imageWithLabel(label: UILabel) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0.0)
        label.layer.render(in: UIGraphicsGetCurrentContext()!)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
   }
}

现在,无论您何时需要使用它来从文本创建图像:

//此标签的自定义根据您的需求进行,您需要哪种字体、什么背景颜色。随意更改。

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 20))
label.numberOfLines = 0
label.textAlignment = .center
label.textColor = UIColor.white
label.backgroundColor = UIColor.black
label.font = UIFont(name: "Montserrat", size: 17)
label.text = "YOUR TEXT HERE"
label.sizeToFit()
let image = UIImage.imageWithLabel(label: label)

0

[yourImageView addSubview:textView]; [canvas addSubview:passingImageView];

「yourImageView 添加子视图 textView; canvas 添加子视图 passingImageView;」
UIGraphicsBeginImageContext(canvas.bounds.size);
[canvas.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
return resultingImage;

你应该取一个UIView,里面放UIImageview,上述代码就可以解决问题。这里的画布是UIView。


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