Converting Text to Image on iOS

后端 未结 4 1923
梦毁少年i
梦毁少年i 2020-12-23 23:38

How to convert Text to Image and show in UIImageview. Can anyone know the conversion from Text to Image?

4条回答
  •  南笙
    南笙 (楼主)
    2020-12-24 00:14

    With Swift 5 and iOS 12, you can choose one the 6 following ways in order to solve your problem.


    #1. Using NSString's draw(at:withAttributes:) method

    In the simplest case where you want to convert a String to a UIImage with some attributes, you can use draw(at:withAttributes:). The following Playground codes show how to get an UIImage from a String using draw(at: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)
    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)
    

    Note that NSAttributedString has a similar method called draw(at:).


    #2. Using NSString's draw(in:withAttributes:) method

    As an alternative to draw(at:withAttributes:), you can use 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)
    

    Note that NSAttributedString has a similar method called draw(in:).


    #3. Using NSString's draw(with:options:attributes:context:) method

    As an alternative to draw(at:withAttributes:) and draw(in:), you can use draw(with:options:attributes:context:). Note that Apple has some recommendations for draw(with:options:attributes:context:):

    This method uses the baseline origin by default. If usesLineFragmentOrigin is not specified, the rectangle’s height will be ignored and the operation considered to be single-line rendering.

    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)
    

    Note that NSAttributedString has a similar method called draw(with:options:context:).


    #4. Using CALayer's render(in:) method

    If you want to capture the text of a UILabel, UITextField or UITextView to a UIImage, you can use render(in:). The following Playground codes show how to snapshot the content text of a UILabel using render(in:):

    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. Using UIView's drawHierarchy(in:afterScreenUpdates:) method

    If you want to capture the text of a UILabel, UITextField or UITextView to a UIImage, you can use drawHierarchy(in:afterScreenUpdates:). Note that Apple has some recommendations for drawHierarchy(in:afterScreenUpdates:):

    Use this method when you want to apply a graphical effect, such as a blur, to a view snapshot. This method is not as fast as the snapshotView(afterScreenUpdates:) method.

    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. Using UIView's snapshotView(afterScreenUpdates:) method

    If it's OK for you to get a UIView instead of a UIImage from your snapshot operation, you can use snapshotView(afterScreenUpdates:). The following Playground code shows how to snapshot the content text of a UILabel into a UIView using 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()
    
    let view = label.snapshotView(afterScreenUpdates: true)
    PlaygroundPage.current.liveView = view
    

提交回复
热议问题