Draw Rectangle On UIImage with Core Graphics

18,272

Solution 1

I feel as if it's not drawing on top of the image which I sent in, it's creating a new image altogether.

No feelings involved. That's literally what this code does.

  1. Creates a new context
  2. Draws a rectangle into it
  3. Makes an image out of the context, and returns it

Between steps 1 and 2, you need to draw your original image into the context.

Also, there is no need to set the line width or stroke color, since you are only filling the rectangle, not stroking it. (If you are seeing red for some reason, it wasn't because of this code; do you have a different view or image that has a red background?)

func drawRectangleOnImage(image: UIImage) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)
    let context = UIGraphicsGetCurrentContext()

    image.draw(at: CGPoint.zero)

    let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)

    CGContextSetFillColorWithColor(context, UIColor.black.CGColor)
    CGContextAddRect(context, rectangle)
    CGContextDrawPath(context, .Fill)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

And you could further simplify by using higher-level UIKit API to draw.

func drawRectangleOnImage(image: UIImage) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)

    image.draw(at: CGPoint.zero)

    let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)

    UIColor.black.setFill()
    UIRectFill(rectangle)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

Solution 2

Objective C version of Kurt Revis answer

-(UIImage *)drawRectangleOnImage:(UIImage *)img rect:(CGRect )rect{
      CGSize imgSize = img.size;
      CGFloat scale = 0;
      UIGraphicsBeginImageContextWithOptions(imgSize, NO, scale);
      [img drawAtPoint:CGPointZero];
      [[UIColor greenColor] setFill];
      UIRectFill(rect);
      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return newImage;
}
Share:
18,272
John Fda
Author by

John Fda

Updated on July 21, 2022

Comments

  • John Fda
    John Fda almost 2 years

    I'm trying to put a rectangle at the center of a UIImage using Core Graphics to look roughly like this:

    enter image description here

    This is my code so far:

    func drawRectangleOnImage(image: UIImage) -> UIImage {
        let imageSize = image.size
        let scale: CGFloat = 0
        UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)
        let context = UIGraphicsGetCurrentContext()
    
        let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)
    
        CGContextSetFillColorWithColor(context, UIColor.blackColor().CGColor)
        CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
        CGContextSetLineWidth(context, 5)
        CGContextAddRect(context, rectangle)
        CGContextDrawPath(context, .Fill)
    
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImage
    }
    

    I feel as if it's not drawing on top of the image which I sent in, it's creating a new image altogether. The entire thing is becoming red, with the rectangle black. I want the black rectangle and the rest of it should still be the same as the image.

    What am I doing wrong?