skip to Main Content

This is my simple function I use for drawing an image in context:

let renderer=UIGraphicsImageRenderer(size: CGSize(width: 330, height: 330))
let img=renderer.image{ ctx in
    let circle=CGRect(x:0,y:0,width: 330, height: 330)
    ctx.cgContext.setFillColor(UIColor.white.cgColor)
    ctx.cgContext.addEllipse(in: circle)
    ctx.cgContext.drawPath(using: .fill)
                
    let image = UIImage(named: "1")!
    image.draw(in: CGRect(x: 80, y: 80, width: 100, height: 100))
}

And the result is following:

enter image description here

As you can see there is output of UIGraphicsImageRenderer with border around ellipse. Why? Border is not defined anywhere, but it is printed.

The image named 1 is the following one:

enter image description here

NOTE:

This issue appears only when compiling ios app. Using playground everything is fine and ok.

2

Answers


  1. OK, the updated code still does not match.

    First, in your posted image, the background is not white.

    Second, even accounting for that, there is no "edge" on the rendered UIImage.

    So, I’m going to make a guess here….

    Assuming you execute the img = renderer.image { .... code block, and then you set imageView.image = img, my suspicion is that you have something like this:

    imageView.backgroundColor = .lightGray
    imageView.layer.cornerRadius = imageView.frame.height / 2.0
    

    So, the lightGray "circle" is the lightGray background anti-aliased to the .cornerRadius.

    I would be that if set:

    imageView.backgroundColor = .clear
    

    and do not set the layer’s cornerRadius (no need to), your ellipse border will be gone.

    If it’s still there, then you need to provide some code that actually reproduces the issue.


    Edit

    I’m still not seeing the "border" when setting the rendered image to an image view, but…

    Doing some debug inspecting and using the "1" image you added, there IS a difference.

    Try this, and see if it gets rid of the border:

    let fmt = UIGraphicsImageRendererFormat()
    fmt.preferredRange = .standard
            
    let renderer = UIGraphicsImageRenderer(size: CGSize(width: 330, height: 330), format: fmt)
            
    

    You can then use either:

    let img = renderer.image { ctx in
        let circle = CGRect(x:0, y:0, width: 330, height: 330)
        ctx.cgContext.setFillColor(UIColor.white.cgColor)
        ctx.cgContext.addEllipse(in: circle)
        ctx.cgContext.drawPath(using: .fill)
                
        if let image = UIImage(named: "1") {
            image.draw(in: CGRect(x: 80, y: 80, width: 100, height: 100))
        }
    }
    

    or Rob’s suggested:

    let img = renderer.image { _ in
        UIColor.white.setFill()
        UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 330, height: 330))
            .fill()
    
        if let image = UIImage(named: "1") {
            image.draw(in: CGRect(x: 80, y: 80, width: 100, height: 100))
        }
    }
    
    Login or Signup to reply.
  2. Does your UIImageView have a cornerRadius applied to its layer? That can cause a thin gray border like you see here. If you create a circular image, like you have with UIGraphicsImageRenderer, you should not need to do any masking or cornerRadius on the UIImageView.


    If you only want to fill the path, and not stroke it, one could use fillPath rather than drawPath.


    FWIW, you could also just bypass the CoreGraphics context and just fill the oval directly:

    let image = renderer.image { _ in
        UIColor.white.setFill()
        UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 330, height: 330))
            .fill()
                    
        UIImage(named: "1")!
            .draw(in: CGRect(x: 80, y: 80, width: 100, height: 100))
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search