Ok ... lo descubrí:
func textToImage(drawText: NSString, inImage: UIImage, atPoint: CGPoint) -> UIImage{
var textColor = UIColor.whiteColor()
var textFont = UIFont(name: "Helvetica Bold", size: 12)!
let scale = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(inImage.size, false, scale)
let textFontAttributes = [
NSFontAttributeName: textFont,
NSForegroundColorAttributeName: textColor,
]
inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))
var rect = CGRectMake(atPoint.x, atPoint.y, inImage.size.width, inImage.size.height)
drawText.drawInRect(rect, withAttributes: textFontAttributes)
var newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
Para llamarlo, simplemente pasa una imagen:
textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))
Los siguientes enlaces me ayudaron a aclarar esto:
Swift - Dibujar texto con drawInRect: withAttributes:
¿Cómo escribir texto en una imagen en Objective-C (iOS)?
El objetivo original era crear una imagen dinámica que pudiera usar AnnotaionView
, como poner un precio en una ubicación determinada en un mapa, y esto funcionó muy bien. Espero que esto ayude a alguien que intenta hacer lo mismo.
Para 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!
}
Para 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!
}
Para Swift 5:
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 = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
] as [NSAttributedString.Key : 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!
}
Mi sencilla solución:
func generateImageWithText(text: String) -> UIImage? { let image = UIImage(named: "imageWithoutText")! let imageView = UIImageView(image: image) imageView.backgroundColor = UIColor.clear imageView.frame = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height) let label = UILabel(frame: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)) label.backgroundColor = UIColor.clear label.textAlignment = .center label.textColor = UIColor.white label.text = text UIGraphicsBeginImageContextWithOptions(label.bounds.size, false, 0) imageView.layer.render(in: UIGraphicsGetCurrentContext()!) label.layer.render(in: UIGraphicsGetCurrentContext()!) let imageWithText = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return imageWithText }
fuente
También puede hacer un CATextLayer.
// 1 let textLayer = CATextLayer() textLayer.frame = someView.bounds // 2 let string = String( repeating: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce auctor arcu quis velit congue dictum. ", count: 20 ) textLayer.string = string // 3 let fontName: CFStringRef = "Noteworthy-Light" textLayer.font = CTFontCreateWithName(fontName, fontSize, nil) // 4 textLayer.foregroundColor = UIColor.darkGray.cgColor textLayer.isWrapped = true textLayer.alignmentMode = kCAAlignmentLeft textLayer.contentsScale = UIScreen.main.scale someView.layer.addSublayer(textLayer)
https://www.raywenderlich.com/402-calayer-tutorial-for-ios-getting-started
fuente
He creado una extensión para usarla en todas partes:
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! } }
Uso: En cualquier lugar de su ViewController donde tenga el tamaño y la etiqueta para agregar, utilícelo de la siguiente manera:
let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)
fuente
Para 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! }
fuente
No puedo ver nada en su pregunta inicial que sugiera que esto debe hacerse exclusivamente en código, entonces, ¿por qué no simplemente agregar un UILabel en el generador de interfaces y agregar restricciones para darle la misma longitud y ancho que su imagen, centrarlo verticalmente y horizontalmente (o como lo necesite), elimine el texto de la etiqueta, establezca la fuente, el tamaño, el color, etc. del texto, según sea necesario (incluida la selección de Autoencogimiento con el tamaño mínimo o escala que necesite) y asegúrese de que el fondo sea transparente.
Luego, simplemente conéctelo a un IBOutlet y configure el texto en código según sea necesario (por ejemplo, en viewWillAppear, o usando un enfoque de ViewModel y configurándolo en la inicialización de su vista / controlador de vista).
fuente
He probado estos componentes básicos. Espero que funcione.
func imageWithText(image : UIImage, text : String) -> UIImage { let outerView = UIView(frame: CGRect(x: 0, y: 0, width: image.size.width / 2, height: image.size.height / 2)) let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: outerView.frame.width, height: outerView.frame.height)) imgView.image = image outerView.addSubview(imgView) let lbl = UILabel(frame: CGRect(x: 5, y: 5, width: outerView.frame.width, height: 200)) lbl.font = UIFont(name: "HelveticaNeue-Bold", size: 70) lbl.text = text lbl.textAlignment = .left lbl.textColor = UIColor.blue outerView.addSubview(lbl) let renderer = UIGraphicsImageRenderer(size: outerView.bounds.size) let convertedImage = renderer.image { ctx in outerView.drawHierarchy(in: outerView.bounds, afterScreenUpdates: true) } return convertedImage }
fuente