Хорошо ... Разобрался:
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
}
Чтобы вызвать это, вы просто передаете изображение:
textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))
Следующие ссылки помогли мне понять это:
Swift - Рисование текста с помощью drawInRect: withAttributes:
Как написать текст на изображении в Objective-C (iOS)?
Первоначальной целью было создать динамическое изображение, которое я мог бы использовать, AnnotaionView
например, для указания цены в заданном месте на карте, и это отлично сработало. Надеюсь, это поможет кому-то, кто пытается сделать то же самое.
Для 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!
}
Для 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!
}
Для 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!
}
My simple solution:
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 }
источник
You can also do a 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
источник
I have created an extension for using it everywhere :
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! } }
Usage : Anywhere on your ViewController where you have the size and the label to add use it as follows -
let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)
источник
For 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! }
источник
I can't see anything in your initial question suggesting that this must be done exclusively in code - so why not simply add a UILabel in interface builder, and add constraints to give it the same length and width as your image, center it vertically and horizontally (or however you need it placed), delete the label text, set the text font, size, colour, etc. as needed (including ticking Autoshrink with whatever minimum size or scale you need), and ensure it's background is transparent.
Then just connect it to an IBOutlet, and set the text in code as needed (e.g. in viewWillAppear, or by using a ViewModel approach and setting it on initialisation of your view/viewcontroller).
источник
I have tried this basic components. Hope it will work.
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 }
источник