मैं iOS स्विफ्ट में एक छवि में पाठ कैसे जोड़ सकता हूं?


82

मैंने चारों ओर देखा है और यह पता लगाने में असफल रहा है कि पाठ कैसे लेते हैं, इसे एक छवि पर ओवरले करें, और फिर दोनों को एक में मिलाएं UIImage

मैंने उन खोज शब्दों का उपयोग करके Google को समाप्त कर दिया है, जिनके बारे में मैं सोच सकता हूं कि यदि किसी के पास कोई समाधान है या कम से कम एक संकेत है तो वे इसे इंगित कर सकते हैं, बहुत सराहना की जाएगी।

जवाबों:


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))

निम्नलिखित लिंक ने मुझे इसे सीधे प्राप्त करने में मदद की:

स्विफ्ट - ड्रॉ के साथ टेक्स्ट ड्रा करें InRect: withAttributes:

Objective-C (iOS) में इमेज पर टेक्स्ट कैसे लिखें?

मूल लक्ष्य एक गतिशील छवि बनाना था, जिसका उपयोग मैं AnnotaionViewकिसी मानचित्र में दिए गए स्थान पर कीमत लगाने के रूप में कर सकता था और इसके लिए यह बहुत अच्छा काम करता था। आशा है कि यह किसी को एक ही काम करने में मदद करता है।

स्विफ्ट 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!
 }

स्विफ्ट 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!
 }

स्विफ्ट 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
अलौकिक! अपना कोड पोस्ट करने के लिए धन्यवाद। और इतनी अच्छी तरह से टिप्पणी की।
एस्पेन

उन पाठों या उनके कंटेनर में टैप की घटनाओं की प्रतिक्रिया हो सकती है?
पीपीरासाई

1
@JadeSync यदि आप जिस ऑब्जेक्ट में छवि आयात कर रहे हैं वह क्लिक करने योग्य है, तो हाँ। लेकिन यह वह पाठ नहीं है जो क्लिक करने योग्य है, यह वह कंटेनर है जिसका अंतिम चित्र उपयोग किया जाता है जिसे क्लिक करने की आवश्यकता होगी। वास्तव में, यह वही है जो मैंने इस छवि के साथ किया था क्योंकि मुझे एक मानचित्र पर क्लिक करने योग्य मार्कर की आवश्यकता थी, और एक छवि में पाठ के लिए मार्कर की आवश्यकता थी। मार्कर में एक क्लिक ईवेंट प्रतिनिधि है, इसलिए यह वह छवि नहीं है जिस पर वे क्लिक कर रहे हैं, लेकिन उस मार्कर में यह शामिल है।
क्रिस्टोफर वेड कैंटली

2
अगर मैं छवि के निचले दाईं ओर बिंदु सेट करता हूं और पाठ बहुत लंबा है तो यह छवि को निकालता है। छवि के दाईं ओर विस्तृत करने के बजाय बिंदु के बाईं ओर संरेखित करने के लिए पाठ प्राप्त करने के बारे में कोई सुझाव?
chickenparm

मैं उस मुद्दे पर भी और स्पष्ट रूप से भाग गया, यह फ़ॉन्ट प्रकार और आकार और छवि के आकार पर निर्भर करता है, जहां आप चाहते हैं कि पाठ छवि में शुरू हो क्योंकि आप पीएनजी छाया पर कदम नहीं रखना चाहते हैं। यह एक परीक्षण था - और - त्रुटि की बात यह है कि मुझे एक चरित्र जोड़ने की आवश्यकता है, यह पता लगाने के लिए कि कितने पिक्सेल शुरू करने के लिए इसे शुरू करने के लिए आगे बढ़ते हैं, फिर वर्णों की संख्या के आधार पर स्लाइडिंग प्रारंभ बिंदु का पता लगाने के लिए एक त्वरित गणना करें (ऊपर) अधिकतम पर आधारित है कि यह कैसा दिखता है)। मैं बहुत जटिल नहीं होना चाहता था, इसलिए मैंने अपने प्रश्न के लिए नंगे समाधान को संबोधित किया।
क्रिस्टोफर वेड कैंटले

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
}

कोड के लिए थैक्स लेकिन फ़ॉन्ट आकार को समायोजित करने के लिए कैसे, हर छवि का आकार अलग पाठ लंबाई के साथ अलग है। मैं इसे कैसे गतिशील बना सकता हूं।
iPhoneDev

मुझे लगता है कि आपको ऑटोश्रिंक का उपयोग करना चाहिए। लेबल की अधिकतम चौड़ाई के लिए अधिकतम फ़ॉन्ट आकार सेट करें और जोड़ें: 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
लव रे का सामान। वैकल्पिक विधि के लिए धन्यवाद!
क्रिस्टोफर वेड कैंटली

2
यहाँ एक दृश्य में एक पाठ परत जोड़ने, एक छवि के लिए नहीं
ब्रेनरे

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
बहुत बढ़िया! इस योगदान के लिए धन्यवाद।
क्रिस्टोफर वेड कैंटली

यह सफेद पृष्ठभूमि दिखाता है, भले ही मैंने पारदर्शी छवि का उपयोग किया हो
EI Captain v2.0

आप इसे क्या देख रहे हैं या सर्वर पर अपलोड कर रहे हैं?
अंकित कुमार गुप्ता

बस छवि ले लो और छवि दृश्य में यह दिखाता है। यह सफेद पृष्ठभूमि दिखाता है
EI Captain v2.0

आपकी छवि को देखने और इसके पर्यवेक्षण में स्पष्ट पृष्ठभूमि होनी चाहिए। यदि आप इसे पीएनजी प्रारूप में सर्वर पर पोस्ट करते हैं तो यह वैसा ही होगा जैसा आप चाहते हैं। वह करो और जांच करो। या इसे स्थानीय स्तर पर एक बार सहेजने का प्रयास करें।
अंकित कुमार गुप्ता

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

मुझे आपके प्रारंभिक प्रश्न में कुछ भी दिखाई नहीं दे रहा है जो यह बताता है कि यह विशेष रूप से कोड में किया जाना चाहिए - तो क्यों नहीं बस इंटरफ़ेस बिल्डर में एक उइलैबेल जोड़ें, और इसे अपनी छवि के समान लंबाई और चौड़ाई देने के लिए बाधाओं को जोड़ें, इसे लंबवत रूप से केंद्रित करें क्षैतिज रूप से (या फिर भी आपको इसे रखने की आवश्यकता है), लेबल टेक्स्ट को हटा दें, आवश्यकतानुसार पाठ फ़ॉन्ट, आकार, रंग, आदि सेट करें (जो भी न्यूनतम आकार या स्केल आपको आवश्यक है, उसके साथ ऑटोशिंक को टिक करें), और यह सुनिश्चित करें कि यह पृष्ठभूमि पारदर्शी है।

फिर बस इसे एक IBOutlet से कनेक्ट करें, और आवश्यकतानुसार पाठ को कोड में सेट करें (जैसे viewWillAppear में, या एक ViewModel दृष्टिकोण का उपयोग करके और इसे अपने दृश्य / viewcontroller के प्रारंभिककरण पर सेट करके)।


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
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.