web-dev-qa-db-fra.com

Comment ajouter du texte à une image dans iOS Swift?

J'ai regardé autour de moi et n'ai pas réussi à comprendre comment prendre un texte, le superposer à une image, puis combiner les deux en une seule UIImage.

J'ai épuisé les mots de Google en utilisant les termes de recherche auxquels je peux penser. Par conséquent, si quelqu'un a une solution ou au moins un indice, il peut le signaler.

Ok ... je l'ai compris:

func textToImage(drawText: NSString, inImage: UIImage, atPoint: CGPoint) -> UIImage{

    // Setup the font specific variables
    var textColor = UIColor.whiteColor()
    var textFont = UIFont(name: "Helvetica Bold", size: 12)!

    // Setup the image context using the passed image
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(inImage.size, false, scale)

    // Setup the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
    ]

    // Put the image into a rectangle as large as the original image
    inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))

    // Create a point within the space that is as bit as the image
    var rect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height)

    // Draw the text into an image
    drawText.drawInRect(rect, withAttributes: textFontAttributes)

    // Create a new image out of the images we have created
    var newImage = UIGraphicsGetImageFromCurrentImageContext()

    // End the context now that we have the image we need
    UIGraphicsEndImageContext()

    //Pass the image back up to the caller
    return newImage

}

Pour l'appeler, il suffit de passer une image:

textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))

Les liens suivants m'ont aidé à comprendre cela:

Swift - Dessiner du texte avec drawInRect: withAttributes:

Comment écrire du texte sur l'image dans Objective-C (iOS)?

Le but initial était de créer une image dynamique que je pouvais utiliser dans une variable AnnotaionView, telle que mettre un prix à un emplacement donné sur une carte, ce qui a bien fonctionné. J'espère que cela aide quelqu'un qui essaie de faire la même chose.

Pour Swift 3:

 func textToImage(drawText text: NSString, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
    let textColor = UIColor.white
    let textFont = UIFont(name: "Helvetica Bold", size: 12)!

    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(image.size, false, scale)

    let textFontAttributes = [
        NSFontAttributeName: textFont,
        NSForegroundColorAttributeName: textColor,
        ] as [String : Any]
    image.draw(in: CGRect(Origin: CGPoint.zero, size: image.size))

    let rect = CGRect(Origin: point, size: image.size)
    text.draw(in: rect, withAttributes: textFontAttributes)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage!
 }

Pour Swift 4:

 func textToImage(drawText text: String, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
    let textColor = UIColor.white
    let textFont = UIFont(name: "Helvetica Bold", size: 12)!

    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(image.size, false, scale)

    let textFontAttributes = [
        NSAttributedStringKey.font: textFont,
        NSAttributedStringKey.foregroundColor: textColor,
        ] as [NSAttributedStringKey : Any]
    image.draw(in: CGRect(Origin: CGPoint.zero, size: image.size))

    let rect = CGRect(Origin: point, size: image.size)
    text.draw(in: rect, withAttributes: textFontAttributes)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage!
 }
140

Ma solution simple:

func generateImageWithText(text: String) -> UIImage
{
    let image = UIImage(named: "imageWithoutText")!

    let imageView = UIImageView(image: image)
    imageView.backgroundColor = UIColor.clearColor()
    imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height)

    let label = UILabel(frame: CGRectMake(0, 0, image.size.width, image.size.height))
    label.backgroundColor = UIColor.clearColor()
    label.textAlignment = .Center
    label.textColor = UIColor.whiteColor()
    label.text = text

    UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0);
    imageView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    label.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let imageWithText = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext();

    return imageWithText
}
15
Darkngs

Vous pouvez également faire un CATextLayer.

    // 1
let textLayer = CATextLayer()
textLayer.frame = someView.bounds

// 2
var string = ""
for _ in 1...20 {
  string += "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce auctor arcu quis velit congue dictum. "
}

textLayer.string = string

// 3
let fontName: CFStringRef = "Noteworthy-Light"
textLayer.font = CTFontCreateWithName(fontName, fontSize, nil)

// 4
textLayer.foregroundColor = UIColor.darkGrayColor().CGColor
textLayer.wrapped = true
textLayer.alignmentMode = kCAAlignmentLeft
textLayer.contentsScale = UIScreen.mainScreen().scale
someView.layer.addSublayer(textLayer)

http://www.raywenderlich.com/90488/calayer-in-ios-with-Swift-10-examples

9
Aspen

J'ai créé une extension pour l'utiliser partout:

import Foundation
import UIKit
extension UIImage {

    class func createImageWithLabelOverlay(label: UILabel,imageSize: CGSize, image: UIImage) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(CGSize(width: imageSize.width, height: imageSize.height), false, 2.0)
        let currentView = UIView.init(frame: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
        let currentImage = UIImageView.init(image: image)
        currentImage.frame = CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height)
        currentView.addSubview(currentImage)
        currentView.addSubview(label)
        currentView.layer.render(in: UIGraphicsGetCurrentContext()!)
        let img = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return img!
    }

}

Utilisation: N'importe où sur votre ViewController où vous avez la taille et l'étiquette à ajouter, utilisez-le comme suit - 

let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)
4
Ankit Kumar Gupta

Pour Swift 4:  

func textToImage(drawText text: NSString, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {


    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(image.size, false, scale)

    image.draw(in: CGRect(Origin: CGPoint.zero, size: image.size))

    let rect = CGRect(Origin: point, size: image.size)

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center



    let attrs = [NSAttributedStringKey.font: UIFont(name: "Helvetica Bold", size: 12)!,NSAttributedStringKey.foregroundColor : UIColor.white , NSAttributedStringKey.paragraphStyle: paragraphStyle]


    text.draw(with: rect, options: .usesLineFragmentOrigin, attributes: attrs, context: nil)



    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage!
}
2
Yasin Aktimur

Je ne vois rien dans votre question initiale qui suggère que cela doit être fait exclusivement dans le code - alors pourquoi ne pas simplement ajouter un UILabel dans le générateur d'interface, et ajouter des contraintes pour lui donner la même longueur et la même largeur que votre image, le centrer verticalement et horizontalement (ou selon vos besoins), supprimez le texte de l'étiquette, définissez la police, la taille, la couleur, etc. du texte (en cochant la case Autoshrink avec la taille ou l'échelle minimale requise) et assurez-vous que l'arrière-plan est transparent.

Ensuite, connectez-le simplement à un IBOutlet et définissez le texte dans le code selon vos besoins (par exemple, dans viewWillAppear ou en utilisant une approche ViewModel et en le définissant lors de l'initialisation de votre view/viewcontroller).

1
Gsp