Many years ago, I wrote a Swift application on macOS that draws the Mandelbrot Set. Some days ago, I decided to rewrite that app and improve it after all this time (I’m not a Swift programmer and I did not write programs for many years even if I have been a C programmer for a long time).
The first version builds the image of the Mandelbrot Set writing in a buffer and then creates the image from it. In particular, the image is drawn by writing a linear array of PixelData where PixelData is defined as follows:
public struct PixelData {
var a:UInt8 = 255
var r:UInt8 = 0
var g:UInt8 = 0
var b:UInt8 = 0
}
while the image is generated by the following code:
func getImage(width w: UInt, height h: UInt, of area: CGRect) -> CGImage {
let pixelCount = Int(w * h)
let bitsPerComponent:Int = 8
let bitsPerPixel:Int = 32
let bytesPerRow: Int = Int(w) * PixelDataSize
let pixels = self.createFractalImage(width: w, height: h, ofRect: area)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo:CGBitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
assert(pixels.count == pixelCount)
var data = pixels
let providerRef = CGDataProvider.init(data: NSData(bytes: &data, length: data.count * PixelDataSize ))!
let image = CGImage.init(
width: Int(w),
height: Int(h),
bitsPerComponent: bitsPerComponent,
bitsPerPixel: bitsPerPixel,
bytesPerRow: bytesPerRow,
space: rgbColorSpace,
bitmapInfo: bitmapInfo,
provider: providerRef,
decode: nil,
shouldInterpolate: true,
intent: CGColorRenderingIntent.defaultIntent
)!
return image
}
As you can see the PixelData struct is formed with 4 UInt8 containing the RGB components. I maintains this approach in the new version and all work fine still today. Now I want to improve the coloring method of the image (based on the traditional Mandelbrot escape and a Palette) introducing a smooth coloring algorithm. For that in general is used an RGB color with float components that of course is different from my implementation. Reading the SwiftUI documentation I see that Color now is defined based on Float. So I am a bit confusing and I want to ask some questions:
The approach I used based on a UInt32 (4 UInt8) buffer seems to be supported, this is true or it is potentially unsafe ? Can be used a buffer based on Color struct based on float, if so how?
There is a better approach in defining buffer that can ensure a better quality ?
In the case the actual approach can be maintained, for building a PixelData struct from float RGB Color it is correct to multiply each component by 255?
I want to know if my implementation is correct or not, and if there are best way to do this. Moreover if other buffer structs can be used.