             guard let data = context.data else { return [] }
             let rgba = data.assumingMemoryBound(to: UInt8.self)
 
-            return stride(from: 0, to: context.width * context.height * 4, by: 4).reduce(into: []) {
-                $0.insert(SimpleColor(red: rgba[$1/* + 0*/], green: rgba[$1 + 1], blue: rgba[$1 + 2], alpha: rgba[$1 + 3]))
-            }
+            let rawValues = stride(from: 0, to: context.width * context.height * 4, by: 4).reduce(into: Set<SimpleColor.RawValues>()) {
+                $0.insert(.init(red: rgba[$1/* + 0*/], green: rgba[$1 + 1], blue: rgba[$1 + 2], alpha: rgba[$1 + 3]))
+            }
+            return Set(rawValues.map(SimpleColor.init))
         }
         return simpleColorsByQuality[quality, default: getSimpleColors(quality: quality)].stored()
     }

            // translate/flip the graphics context (for transforming from CG* coords to UI* coordinates)
            context.translateBy(x: 0.0, y: -1.0)
            context.scaleBy(x: 1.0, y: -1.0)
            
            context.setBlendMode(.colorBurn)
            context.draw(cgImage, in: rect)
            context.clip(to: rect, mask: cgImage)
            context.addRect(rect)
            context.drawPath(using: .fill)
        }
        
        guard let cgImage = cgImage else { return nil }
        let rect = CGRect(origin: .zero, size: size)
        
        if #available(iOS 10, *) {
            let renderer = UIGraphicsImageRenderer(size: size)
            return renderer.image {


public extension UIImage {
    private struct SimpleColor<Val: UnsignedInteger>: Hashable {
        struct RawValues: Hashable {
            let rgb: (red: Val, green: Val, blue: Val)
            let alpha: Val

            func hash(into hasher: inout Hasher) {
                hasher.combine(rgb.red)
                hasher.combine(rgb.green)
                hasher.combine(rgb.blue)
                hasher.combine(alpha)
            }

            init(red: Val, green: Val, blue: Val, alpha: Val) {
                self.rgb = (red, green, blue)
                self.alpha = alpha
            }

            static func ==(lhs: RawValues, rhs: RawValues) -> Bool {
                return lhs.rgb == rhs.rgb && lhs.alpha == rhs.alpha
            }
        }
        let raw: RawValues

        let rgba: Lazy<RGBA>
        let hsba: Lazy<HSBA>

        var uiColor: UIColor { return rgba.value.color }
        var intensity: CGFloat { return hsba.value.saturation + hsba.value.brightness }

        func hash(into hasher: inout Hasher) {
            hasher.combine(raw)
        }

        init(rawValues: RawValues) {
            raw = rawValues

            let lazyRGBA = Lazy {
                RGBA(
                    red: CGFloat(rawValues.rgb.red) / 255.0,
                    green: CGFloat(rawValues.rgb.green) / 255.0,
                    blue: CGFloat(rawValues.rgb.blue) / 255.0,
                    alpha: CGFloat(rawValues.alpha) / 255.0
                )
            }
            rgba = lazyRGBA
            hsba = Lazy { lazyRGBA.value.toHSBA() }
        }

        static func ==(lhs: SimpleColor, rhs: SimpleColor) -> Bool {
            return lhs.raw == rhs.raw
        }
    }
