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.
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!
}
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!
}
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
}
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
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)
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!
}
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).