0

I've been trying for a long time to find the best way to add a UILabel with its background color to a UIImage. I need to add a exact replica of the label that is being shown on the screen to the image, if that makes sense to you.

The absolute easiest way I found to do this was by using renderInContext like this:

    UIGraphicsBeginImageContext(self.view.bounds.size)
    self.view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let resultingImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    self.imageViewer.image = resultingImage
    UIGraphicsEndImageContext()

But this makes the resulting image pixelated. I'm also aware you can use write text to the image like this:

func addTextToImage(image:UIImage, text:NSString, pointof: CGPoint) -> UIImage{

    let font:UIFont = UIFont.boldSystemFontOfSize(14)
    let color: UIColor = UIColor.whiteColor()
    let attributeDict:NSDictionary = [NSFontAttributeName : font, NSForegroundColorAttributeName : color]

    UIGraphicsBeginImageContext(image.size)
    image.drawInRect(CGRectMake(0, 0, image.size.width, image.size.height))

    let rect: CGRect = CGRectMake(pointof.x, pointof.y, image.size.width, image.size.height)


    text.drawInRect(CGRectIntegral(rect), withAttributes:attributeDict as [NSObject : AnyObject])

    let contxt:CGContextRef = UIGraphicsGetCurrentContext()

    let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return newImage
}

But that's a "messy" way to do it I think, especially since the font size for some reason does not match the one in the label.

So my questions follow: Is there any way to make the image I get using the first method less pixelated? Or is there any easier way of achieving the effect I want?

The reason I want this is because I have a UITextField which I write text to over the image, but I guess it's easier to add a label than a text field to an image.

Any suggestions on how to achieve this would be appreciated.

martin
  • 1,894
  • 4
  • 37
  • 69

1 Answers1

3

You aren't taking the scale factor into the account. Use

UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,YES,0.0)

instead of

UIGraphicsBeginImageContext(self.view.bounds.size)

The latter assumes that the scale factor is 1, which is almost never the case anymore because all the current devices have retina displays.

Using a smaller scale factor than the real one would lead to smaller images that will look pixelated when getting displayed on a retina screen.

Cihan Tek
  • 5,349
  • 3
  • 22
  • 29
  • And if this should support iPhone 6plus, do I need to use 3.0 (3x) instead of 2.0? – martin Feb 15 '15 at 15:49
  • Sorry, I mistyped the parameter value :) Just edited my answer to fix it. You have to set the scale parameter to 0.0, which will cause the method to always use the correct scale factor in all devices. – Cihan Tek Feb 15 '15 at 15:52
  • Check out this Swift extension to do this [http://stackoverflow.com/a/33545910/517707](http://stackoverflow.com/a/33545910/517707) – Heberti Almeida Nov 05 '15 at 13:36