Ok ... wymyśliłem to:
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
}
Aby to nazwać, wystarczy przekazać obraz:
textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))
Poniższe linki pomogły mi w zrozumieniu tego:
Swift - Rysowanie tekstu za pomocą drawInRect: withAttributes:
Jak pisać tekst na obrazie w Objective-C (iOS)?
Pierwotnym celem było stworzenie dynamicznego obrazu, który mógłbym wykorzystać AnnotaionView
np. Do umieszczenia ceny w danym miejscu na mapie i to wyszło świetnie. Mam nadzieję, że pomoże to komuś, kto spróbuje zrobić to samo.
Dla 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!
}
Dla 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!
}
Dla 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!
}
Moje proste rozwiązanie:
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 }
źródło
Możesz także zrobić 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
źródło
Stworzyłem rozszerzenie do używania go wszędzie:
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! } }
Użycie: W dowolnym miejscu w kontrolerze ViewController, w którym masz rozmiar i etykietę do dodania, użyj go w następujący sposób -
let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)
źródło
Dla 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! }
źródło
W twoim początkowym pytaniu nie widzę niczego, co sugerowałoby, że należy to zrobić wyłącznie w kodzie - dlaczego więc po prostu nie dodać UILabel w narzędziu do tworzenia interfejsów i dodać ograniczenia, aby nadać mu taką samą długość i szerokość jak obraz, wyśrodkować go w pionie i poziomo (lub jakkolwiek potrzebujesz), usuń tekst etykiety, ustaw czcionkę tekstu, rozmiar, kolor itp. w razie potrzeby (w tym zaznaczenie Autoshrink z jakimkolwiek minimalnym rozmiarem lub skalą, jakiej potrzebujesz) i upewnij się, że tło jest przezroczyste.
Następnie po prostu podłącz go do IBOutlet i ustaw tekst w kodzie zgodnie z potrzebami (np. W viewWillAppear lub używając podejścia ViewModel i ustawiając go podczas inicjalizacji widoku / kontrolera widoku).
źródło
Wypróbowałem te podstawowe komponenty. Mam nadzieję, że to zadziała.
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 }
źródło