I'm using this code to get CGLayer
with alpha radial gradient:
let scale = UIScreen.main.scale
let roundedSize = round(size)
var canvasSize = size_t(roundedSize)
canvasSize *= size_t(scale)
let colorSpace = CGColorSpaceCreateDeviceRGB()
context = CGContext(data: nil,
width: canvasSize,
height: canvasSize,
bitsPerComponent: 8,
bytesPerRow: canvasSize * 4,
space: colorSpace,
bitmapInfo: CGBitmapInfo.alphaInfoMask.rawValue & CGImageAlphaInfo.premultipliedLast.rawValue)
cgLayer = CGLayer(context, size: CGSize(width: canvasSize, height: canvasSize), auxiliaryInfo: nil)
let ctx = cgLayer.context
var ctxRect = CGRect.zero
ctxRect.size.height = CGFloat(canvasSize)
ctxRect.size.width = ctxRect.size.height
ctx?.clear(ctxRect)
ctxRect = ctxRect.insetBy(dx: 1.0, dy: 1.0)
let innerColor = UIColor(white: !whiteBrush ? 1.0 : 0.0, alpha: CGFloat(min(hardness + 0.5, 1))).cgColor
let outerColor = innerColor.copy(alpha: 0.0)
if hardness != 1.0 {
var locations = [CGFloat](repeating: 0.0, count: 2)
locations[0] = hardness
locations[1] = 1.0
let colors = [innerColor, outerColor]
let colorsCF = colors as CFArray
let gradient = CGGradient(colorsSpace: colorSpace, colors: colorsCF, locations: &locations)
let center = CGPoint(x: CGFloat(canvasSize) / 2.0, y: CGFloat(canvasSize) / 2.0)
if let gradient = gradient {
ctx?.drawRadialGradient(gradient,
startCenter: center,
startRadius: 0.0,
endCenter: center,
endRadius: center.x - 1.0,
options: .drawsAfterEndLocation)
}
It should render a smooth gradient but instead of this I've got two different results (images are white, looks ok on dark mode :D): One is a poor gradient with a solid center (solid center is expected if hardness is > 0.5)
Or with similar values of hardness and size, something more blurry and ugly:
How I can get better results with creating gradients? Instead of smooth transition, I have some pixelated half ovals, looks ugly. I want something like a brush in paint, that gives a smooth transition on the alpha channel.
I'm using this code to "render" them:
var image: UIImage? {
context.setFillColor(gray: 1, alpha: 0)
//CGContextSetFillColorWithColor(_context, [[UIColor clearColor] CGColor]);
context.fill(context.boundingBoxOfClipPath)
context.draw(cgLayer, at: CGPoint.zero)
let cgImage = context.makeImage()
var image: UIImage?
if let cgImage = cgImage {
image = UIImage(cgImage: cgImage, scale: 1, orientation: .up)
}
return image
}