iOS Swift에서 이미지에 텍스트를 어떻게 추가합니까?


82

나는 주위를 둘러 보았지만 텍스트를 가져 와서 이미지에 오버레이 한 다음 두 개를 하나로 결합하는 방법을 알아내는 데 실패했습니다. UIImage .

나는 내가 생각할 수있는 검색어를 사용하여 구글을 지쳤다. 그래서 누군가가 해결책이나 적어도 힌트가 있다면 그들이 그것을 가리킬 수 있다면 대단히 감사 할 것이다.

답변:


186

좋아 ... 나는 그것을 알아 냈다.

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

}

이를 호출하려면 이미지를 전달하면됩니다.

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

1
매우 유용합니다! 코드를 게시 해 주셔서 감사합니다. 댓글이 너무 좋아요.
Aspen

해당 텍스트 또는 컨테이너가 탭 이벤트에 대한 응답을 확인할 수 있습니까?
PPrasai

1
이미지를 가져올 개체를 클릭 할 수있는 경우 @JadeSync, 예. 그러나 클릭 할 수있는 것은 텍스트가 아니라 클릭 할 수 있어야하는 최종 이미지가 사용되는 컨테이너입니다. 실제로지도에 클릭 가능한 마커를 표시하는 방법이 필요했고 마커에는 이미지에 텍스트가 있어야했기 때문에이 이미지를 사용했습니다. 마커에는 클릭 이벤트 대리자가 있으므로 클릭하는 이미지가 아니라 포함 된 마커입니다.
Christopher Wade Cantley

2
포인트를 이미지의 오른쪽 하단으로 설정하고 텍스트가 너무 길면 이미지에서 확장됩니다. 텍스트를 이미지에서 오른쪽으로 확장하는 대신 지점의 왼쪽에 정렬하는 방법에 대한 제안이 있습니까?
chickenparm

솔직히이 문제는 글꼴 유형과 크기 및 PNG 그림자를 밟고 싶지 않을 수도 있으므로 이미지에서 텍스트를 시작하려는 이미지의 크기에 따라 달라집니다. 이것은 내가 문자를 추가하고 시작점을 이동하기 위해 몇 픽셀을 이동해야하는지 파악한 다음 문자 수에 따라 슬라이딩 시작점을 계산하기 위해 빠른 계산을 수행해야하는 시행 착오 작업이었습니다. 그것이 어떻게 보이는지에 따라 최대로). 나는 너무 복잡해지고 싶지 않았기 때문에 내 질문에 대한 해결책을 제시했습니다.
크리스토퍼 웨이드 캔 틀리

20

내 간단한 해결책 :

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
}

코드에 대한 Thaks이지만 글꼴 크기를 조정하는 방법, 모든 이미지 크기는 텍스트 길이에 따라 다릅니다. 이것을 어떻게 동적으로 만들 수 있습니까?
iPhoneDev

Autoshrink를 사용해야한다고 생각합니다. 레이블의 최대 너비에 대한 최대 글꼴 크기를 설정하고 다음을 추가합니다. label.adjustsFontSizeToFitWidth = true & label.minimumScaleFactor = 0.5
Darkngs

모서리에 정렬 된 레이블 텍스트를 추가하는 방법이 있습니까?
Ashh

11

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


1
Ray의 물건을 좋아하십시오. 대체 방법에 감사드립니다!
Christopher Wade Cantley

2
이미지가 아닌보기에 텍스트 레이어를 추가하는 것
brainray

1
텍스트를 세로로 정렬하려는 경우 언급 할 가치가 있습니다. stackoverflow.com/questions/4765461/…
JKRT

5

어디에서나 사용할 수있는 확장 프로그램을 만들었습니다.

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

}

사용법 : 크기와 추가 할 레이블이있는 ViewController의 모든 위치에서 다음과 같이 사용하십시오.

let newImageWithOverlay = UIImage.createImageWithLabelOverlay(label: labelToAdd, imageSize: size, image: editedImage)

1
대박! 기여해 주셔서 감사합니다.
Christopher Wade Cantley

투명 이미지를 사용해도 흰색 배경이
EI Captain v2.0

보기에 올리거나 서버에 업로드하는 것은 무엇입니까?
Ankit Kumar Gupta

이미지를 가져 와서 이미지보기로 보여줍니다. 그것은 흰색 배경을 보여줍니다
EI 캡틴 2.0

이미지보기와 수퍼 뷰의 배경이 분명해야합니다. png 형식으로 서버에 게시하면 원하는대로됩니다. 그것을하고 확인하십시오. 또는 로컬에 한 번 저장해보십시오.
Ankit Kumar Gupta

3

신속한 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!
}

1

나는 이것이 코드로 독점적으로 수행되어야한다고 제안하는 초기 질문에서 아무것도 볼 수 없습니다. 그러니 인터페이스 빌더에서 UILabel을 추가하고 제약 조건을 추가하여 이미지와 동일한 길이와 너비를 부여하고 수직으로 중앙에 배치하고 가로로 (또는 배치해야하는 경우), 레이블 텍스트를 삭제하고, 필요에 따라 텍스트 글꼴, 크기, 색상 등을 설정하고 (필요한 최소 크기 또는 배율로 자동 축소를 선택하는 것을 포함하여) 배경이 투명한지 확인합니다.

그런 다음 IBOutlet에 연결하고 필요에 따라 코드에서 텍스트를 설정합니다 (예 : viewWillAppear에서 또는 ViewModel 접근 방식을 사용하고 뷰 / 뷰 컨트롤러 초기화시 설정).


0

이 기본 구성 요소를 시도했습니다. 그것이 효과가 있기를 바랍니다.

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
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.