]> git.r.bdr.sh - rbdr/patterns/blame_incremental - Sources/Patterns/TileImage.swift
Use CoreGraphics to draw instead of SwifTUI
[rbdr/patterns] / Sources / Patterns / TileImage.swift
... / ...
CommitLineData
1import CoreGraphics
2
3struct TileImage {
4 static func image(_ design: TileDesign, pixelSize: CGFloat, foregroundColor: CGColor? = nil, backgroundColor: CGColor? = nil) -> CGImage {
5
6 let fg = foregroundColor ?? .init(red: 0, green: 0, blue: 0, alpha: 255)
7 let bg = backgroundColor ?? .init(red: 255, green: 255, blue: 255, alpha: 255)
8
9 // Convert the array to image data
10
11 let pixels: [UInt8] = design.pixels().map({ x in
12 var color = bg
13 if x == 0 {
14 color = fg
15 }
16 let components = color.components ?? [0,0,0,1]
17 return components.map({ c in
18 UInt8(round(c * 255))
19 })
20 }).reduce([], +)
21
22 // Generate the image
23
24 let pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: pixels.count)
25 pointer.initialize(from: pixels, count: pixels.count)
26 let width = 8.0
27 let height = 8.0
28 let bitsPerComponent = 8
29 let componentCount = 4
30 let bitsPerPixel = bitsPerComponent * componentCount
31 let colorSpace = CGColorSpaceCreateDeviceRGB()
32
33 let bitmapInfo = CGBitmapInfo([.byteOrderDefault, CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)])
34 let provider = CGDataProvider(dataInfo: nil, data: pointer, size: Int(width * height * 4)) { _, _, _ in
35 return
36 }!
37
38 let image = CGImage(
39 width: Int(width),
40 height: Int(height),
41 bitsPerComponent: bitsPerComponent,
42 bitsPerPixel: bitsPerPixel,
43 bytesPerRow: Int(width) * componentCount,
44 space: colorSpace,
45 bitmapInfo: bitmapInfo,
46 provider: provider,
47 decode: nil, shouldInterpolate: false, intent: CGColorRenderingIntent.defaultIntent)!
48
49 return image.resize(size: CGSize(width: width * pixelSize, height: height * pixelSize)) ?? image
50 }
51}