如何在 iOS Swift 中向图像添加文本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28906914/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I add text to an image in iOS Swift?
提问by Christopher Wade Cantley
I have looked around and have been unsuccessful at figuring out how take text, overlay it on an image, and then combine the two into a single UIImage
.
我环顾四周并没有成功弄清楚如何获取文本,将其叠加在图像上,然后将两者合并为一个UIImage
.
I have exhausted Google using the search terms I can think of so if anyone has a solution or at least a hint they can point to it would be greatly appreciated.
我已经使用我能想到的搜索词用尽了谷歌,所以如果有人有解决方案或至少是他们可以指出的提示,我们将不胜感激。
回答by Christopher Wade Cantley
Ok... I figured it out:
好吧...我想通了:
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
}
To call it, you just pass in an image:
要调用它,您只需传入一个图像:
textToImage("000", inImage: UIImage(named:"thisImage.png")!, atPoint: CGPointMake(20, 20))
The following links helped me get this straight:
以下链接帮助我明白了这一点:
Swift - Drawing text with drawInRect:withAttributes:
Swift - 使用 drawInRect:withAttributes 绘制文本:
How to write text on image in Objective-C (iOS)?
如何在 Objective-C (iOS) 中在图像上写入文本?
The original goal was to create a dynamic image that I could use in an AnnotaionView
such as putting a price at a given location on a map and this worked out great for it. Hope this helps someone trying to do the same thing.
最初的目标是创建一个动态图像,我可以AnnotaionView
将其用于诸如在地图上的给定位置标价之类的事情,这对它非常有用。希望这有助于有人尝试做同样的事情。
For Swift 3:
对于 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!
}
For Swift 4:
对于 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!
}
For Swift 5:
对于 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!
}
回答by Darkngs
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
}
回答by Aspen
You can also do a CATextLayer.
你也可以做一个 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
https://www.raywenderlich.com/402-calayer-tutorial-for-ios-getting-started
回答by Ankit Kumar Gupta
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 -
用法:在您的 ViewController 上任何有大小和标签的地方都可以使用它,如下所示 -
let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)
回答by Yasin Aktimur
For swift 4:
对于快速 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!
}
回答by Gsp
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.
我在您最初的问题中看不到任何内容表明这必须完全在代码中完成 - 那么为什么不简单地在界面构建器中添加一个 UILabel,并添加约束以使其与您的图像具有相同的长度和宽度,将其垂直居中并水平(或您需要的任何位置),删除标签文本,根据需要设置文本字体、大小、颜色等(包括使用您需要的任何最小大小或比例勾选自动收缩),并确保其背景是透明的。
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).
然后只需将其连接到 IBOutlet,并根据需要在代码中设置文本(例如,在 viewWillAppear 中,或通过使用 ViewModel 方法并在视图/视图控制器的初始化时设置它)。
回答by Muhammad Haroon Iqbal
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
}