adding text to a UIImage doesn't seem to work

I have a saved image in a UIImageView variable.

I'm trying to get the text "Hello" added to this image so that it is all 1 combined image.


I've tried a couple of different things but can't seem to figure it out or get it to work.

Any help would be greatly appreciated:


Here's my code:

//Set the variable that holds the Image to the new image with the text added:

/Attempt #1 function call:

ImageView.image = textToImage(drawText: "Hello", inImage: CameraImageView.image!, atPoint: CGPoint(x: 20, y: 20))

//Attempt #2 function Call:

ImageView.image = generateImageWithText(text: "Hello")


//function #1:

func textToImage(drawText text: String, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {

let textColor = UIColor.white

let textFont = UIFont(name: "Marker Felt", size: 12)!

let scale = image.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()

// added this line to try and get it to work too but it didn't:

ImageView.image = newImage

UIGraphicsEndImageContext()

return newImage!

}


//funtion 2:

func generateImageWithText(text: String) -> UIImage

{

let image = CameraImageView.image

let imageView = UIImageView(image: image)

imageView.backgroundColor = UIColor.clear

imageView.frame = CGRect(origin: CGPoint(x: 0, y: 0), size: (image?.size)!)

print("Image size: \(image?.size)")

let label = UILabel(frame: CGRect(origin: CGPoint(x: 20, y: 20), size: CGSize(width: 3024.0, height: 4032.0)/*(width://image?.size)!*/))

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!

}

Accepted Reply

Do you want only to display or do you want to save the combined image ?


For the first, you should

- create a UIView

- in its draw function, draw the image

- then, in draw, draw the text.


You'll have an interesting discussion on various solutions here

https://stackoverflow.com/questions/32006128/how-to-merge-two-uiimages

Replies

Do you want only to display or do you want to save the combined image ?


For the first, you should

- create a UIView

- in its draw function, draw the image

- then, in draw, draw the text.


You'll have an interesting discussion on various solutions here

https://stackoverflow.com/questions/32006128/how-to-merge-two-uiimages

I think you go the right idea. Combine Image A with Image B to create an Image C.


I want to display Image C on the phone, in which then other actions can be taken.

I don't want to "save" it to the photo library or anything like that.


I'll give that a shot.


thanks for the help!

>> I've tried a couple of different things but can't seem to figure it out or get it to work.


Yes, but what doesn't work? Are you getting empty images? Images with a copy of the original image but no text? Text and no image?


Your original #1 approach looks about correct, so I would suggest to keep working at it, rather than flailing around trying different approaches.


Keep in mind that in #1 you're drawing into a CGContext, and IIRC the CGContext system is upside down relative to the UIKit coordinate system. You may have to transform your drawing coordinates.


The other thing that looks wrong is passing the value of image.scale into the "scale" parameter of "UIGraphicsBeginImageContextWithOptions". These are scales with different purposes. Normally, you should always specify 0.0 for the "scale" parameter, indicating that you want a retina-resolution image compatible with the particular device screen. By contrast, the image scale is an arbitrary scale factor the image itself.

Thanks Quincey for the insights.

Yes I get back the image I started with, but no text shown on it.

So it's like I press the button and it does nothing.


In the second one I did get the text on there but it was extremely small (like a few pixels in size.)

I did print the size, which is where I came up with those numbers for the UIImageview.image.size.

let label = UILabel(frame: CGRect(origin: CGPoint(x: 20, y: 20), size: CGSize(width: 3024.0, height: 4032.0)

when I started playing around with those sizes, it did seem to zoom in on the text a little but it zoomed in on the whole picture.

Like it put the text on it really small, and then zoomed in on that part of the image, which is incorrect as well.


either way thanks for the help and advice.

I tried your first method and succeeded. I guess maybe the CGPoint you imported is bigger than the size of the picture.

ok. I figured out that there are a couple ways to add text to an image. and they do work provided 1 thing:

the image is saved in the attributes folder.


I'm taking the image from the camera capture session.

So have Camera Capture session. Capture the image, save it into a UIImageView field.

Then try and add the text to that UIImageView field.

It seems like it won't add the text.

Works great if it's a pre-saved image in the attributes folder of the project or pulled from the photo-library.

but it won't update the image in UIImageView field that is not saved someplace else.


I've tried all the suggestions above nothing seems to work.

Beginnning to think this is a bug with IOS 11.4.

All,

Thank you to all for your suggestions, help and responses!

I went with Claude31's answer as the correct one as that got me past the hurdle.


Managed to figure this out and why it wasn't working.

An image captured from the camera session and not saved, can not be updated. I think it's because it doesn't know how to handle the image as it doesn't know the type of image (i.e. .png, .jpg. gif, etc.). So I created an image with a clear or blank background in paint and added the words to that.

I then take the captured camera image save it into a variable, and apply the image with the text saved in the assets folder and apply that as the top layer. Here's the code:

  let bottomImage = CameraImageView.image
var topImage = UIImage(named: "HelloWorld.png")
let size = CGSize(width: 242, height: 243)
UIGraphicsBeginImageContext(size)
let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
bottomImage!.draw(in: areaSize)
topImage!.draw(in: areaSize, blendMode: CGBlendMode(rawValue: 0)!, alpha: 0.8)
//the constant below is what takes the 2 images from the context and merges them into 1 new image
let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
//set the combined image into the empty Imageview variable, and then display it
ImageViewEmpty.image = newImage
UIGraphicsEndImageContext()
ImageViewEmpty.isHidden = false