Draw text in the right corner of the image

I want to draw text in the upper or lower right corner of UIImage. I have an extension that is great for drawing text, but the problem is the placement of the text on the right side of the screen (since the text is being clipped).

Here's the extension:

extension UIImage {

func addText(drawText: NSString, atPoint: CGPoint, textColor: UIColor?, textFont: UIFont?) -> UIImage{

    // Setup the font specific variables
    var _textColor: UIColor
    if textColor == nil {
        _textColor = UIColor.white
    } else {
        _textColor = textColor!
    }

    var _textFont: UIFont
    if textFont == nil {
        _textFont = UIFont.systemFont(ofSize: 50)
    } else {
        _textFont = textFont!
    }

    // Setup the image context using the passed image
    UIGraphicsBeginImageContext(size)

    // Setup the font attributes that will be later used to dictate how the text should be drawn
    let textFontAttributes = [
        NSFontAttributeName: _textFont,
        NSForegroundColorAttributeName: _textColor,
        ] as [String : Any]

    // Put the image into a rectangle as large as the original image
    draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

    // Create a point within the space that is as bit as the image
    let rect = CGRect(x: atPoint.x, y: atPoint.y, width: size.width, height: size.height)


    // Draw the text into an image
    drawText.draw(in: rect, withAttributes: textFontAttributes)

    // Create a new image out of the images we have created
    let newImage = UIGraphicsGetImageFromCurrentImageContext()

    // End the context now that we have the image we need
    UIGraphicsEndImageContext()

    //Pass the image back up to the caller
    return newImage!
}
}

      

The problem is if the text is too long or too large, it will be off-screen. I would need to change the origin to write the text from right to left, so that it only takes up space to the left and not to the right of the screen. How can i do this?

actual problem

what I want

+3


source to share


1 answer


There is a simple function call to get the "bounding box" for a string. You can use this to position the text to be drawn in the image:

    // get the bounding-box for the string
    let stringSize = drawText.size(attributes: textFontAttributes)

    // position the bounding-box at the bottom-right corner of the image
    let x = self.size.width - ceil(stringSize.width)
    let y = self.size.height - ceil(stringSize.height)

    let rect = CGRect(x: x, y: y, width: stringSize.width, height: stringSize.height)

    // Draw the text into an image
    drawText.draw(in: rect, withAttributes: textFontAttributes)

      

Note that this code example places text in the lower right corner - ignores the parameter atPoint

. You will probably change this to a type parameter whichCorner

and then compute the position x

and accordingly y

.

By the way ... drawText

- a terrible name for a variable - it sounds like a function. It is much more convenient to use something like textToDraw

.




Following is the modified function using a parameter atCorner

where the values ​​are:

        +-----------+ 
        | 0       1 | 
        |           | 
        |           | 
        | 3       2 |
        +-----------+

      




Edit: Using the right-align style (as suggested by Tilina Chamin Hewagama) has some advantages. This edited version even handles text with "\n"

embedded line breaks.

extension UIImage {

    func addText(textToDraw: NSString, atCorner: Int, textColor: UIColor?, textFont: UIFont?) -> UIImage {

        // Setup the font specific variables
        var _textColor: UIColor
        if textColor == nil {
            _textColor = UIColor.white
        } else {
            _textColor = textColor!
        }

        var _textFont: UIFont
        if textFont == nil {
            _textFont = UIFont.systemFont(ofSize: 50)
        } else {
            _textFont = textFont!
        }

        // Setup the image context using the passed image
        UIGraphicsBeginImageContext(size)

        // Put the image into a rectangle as large as the original image
        draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))

        let titleParagraphStyle = NSMutableParagraphStyle()

        // Setup the font attributes that will be later used to dictate how the text should be drawn
        let textFontAttributes = [
            NSFontAttributeName: _textFont,
            NSForegroundColorAttributeName: _textColor,
            NSParagraphStyleAttributeName: titleParagraphStyle
            ] as [String : Any]

        // get the bounding-box for the string
        var stringSize = textToDraw.size(attributes: textFontAttributes)

        // draw in rect functions like whole numbers
        stringSize.width = ceil(stringSize.width)
        stringSize.height = ceil(stringSize.height)

        var rect = CGRect(origin: CGPoint.zero, size: self.size)

        switch atCorner {

        case 1:
            // top-right
            titleParagraphStyle.alignment = .right

        case 2:
            // bottom-right
            rect.origin.y = self.size.height - stringSize.height
            titleParagraphStyle.alignment = .right

        case 3:
            // bottom-left
            rect.origin.y = self.size.height - stringSize.height

        default:
            // top-left
            // don't need to change anything here
            break

        }

        // Draw the text into an image
        textToDraw.draw(in: rect, withAttributes: textFontAttributes)

        // Create a new image out of the images we have created
        let newImage = UIGraphicsGetImageFromCurrentImageContext()

        // End the context now that we have the image we need
        UIGraphicsEndImageContext()

        //Pass the image back up to the caller
        return newImage!
    }

}

      

+2


source







All Articles