]>
Commit | Line | Data |
---|---|---|
1 | import CoreGraphics | |
2 | ||
3 | struct 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 | } |