A Swift package that extracts the dominant color from an image and determines the optimal foreground color for readability.
이미지에서 지배적인 색상을 추출하고 가독성을 위한 최적의 전경색을 결정하는 Swift 패키지입니다.
- 엣지 가중 K-Means 클러스터링 — 이미지 가장자리 색상에 3배 가중치를 부여하여 더 자연스러운 색상 추출
- 색상 순화(Taming) — HSL 밝기를 제한하여 지나치게 선명한 배경색 방지
- WCAG 접근성 준수 — 상대 휘도 기반으로 흰색/검정 텍스트를 자동 선택
- 크로스 플랫폼 — iOS 15+ / macOS 12+ 지원
Package.swift에 의존성을 추가하세요:
dependencies: [
.package(url: "https://github.com/eraser3031/ChoosePerfectColor.git", from: "1.0.0")
]또는 Xcode에서: File → Add Package Dependencies에서 레포지토리 URL을 입력하세요.
import ChoosePerfectColor
// 한 번에 분석
let (bg, fg) = PerfectColor.analyze(image: cgImage)
// 또는 단계별로
let raw = PerfectColor.extractDominantColor(from: cgImage)
let tamed = PerfectColor.tameColor(raw)
let foreground = PerfectColor.chooseForeground(for: tamed)let (bg, fg) = PerfectColor.analyze(image: cgImage)
Text("Hello")
.foregroundStyle(fg.color)
.background(bg.color)let color = rgb.color // SwiftUI Color
let hex = rgb.hexString // "#FF5A2D"| 메서드 | 설명 |
|---|---|
PerfectColor.extractDominantColor(from:) |
엣지 가중 k-means로 지배색 추출 (k=5, 64×64 다운샘플) |
PerfectColor.tameColor(_:maxLightness:) |
채도 높은 색상의 밝기 제한 (기본값 0.45) |
PerfectColor.chooseForeground(for:) |
WCAG 2.0 휘도 기반 흰색/검정 RGB 반환 |
PerfectColor.analyze(image:maxLightness:) |
추출 → 순화 → 전경색 선택을 한 번에 수행 |
RGB.color |
SwiftUI Color로 변환 |
RGB.hexString |
16진수 문자열로 변환 (예: "#FF5A2D") |
- CoreGraphics로 이미지를 64×64로 다운샘플링
- 중심에서의 거리에 따라 픽셀 가중치 부여 — 가장자리 3배, 중심 1배
- K-Means 클러스터링 (k=5, 10회 반복)으로 유사 색상 그룹화
- 총 가중치가 가장 큰 클러스터를 지배색으로 선택
- 색상이 너무 선명하면 순화 (HSL 채도 > 0.3이고 밝기 > 0.45인 경우)
- 전경색 결정 — 배경 휘도 ≤ 0.25이면 흰색, 아니면 검정
Example/ChoosePerfectColorDemo/에 예시 iOS 앱이 포함되어 있습니다. Xcode에서 .xcodeproj를 열면 로컬 패키지 의존성이 이미 설정되어 있습니다.
사진 라이브러리에서 이미지를 선택하면 추출된 배경색/전경색이 부드러운 애니메이션과 함께 표시됩니다.
- Edge-Weighted K-Means Clustering — Prioritizes colors from image edges (3×) over the center (1×) for more aesthetically pleasing results
- Color Taming — Reduces overly vivid colors by capping HSL lightness, preventing harsh backgrounds
- WCAG-Compliant Foreground — Automatically picks white or black text based on relative luminance
- Cross-Platform — Supports iOS 15+ and macOS 12+
Add the dependency to your Package.swift:
dependencies: [
.package(url: "https://github.com/eraser3031/ChoosePerfectColor.git", from: "1.0.0")
]Or in Xcode: File → Add Package Dependencies and enter the repository URL.
import ChoosePerfectColor
// One-call analysis
let (bg, fg) = PerfectColor.analyze(image: cgImage)
// Or step by step
let raw = PerfectColor.extractDominantColor(from: cgImage)
let tamed = PerfectColor.tameColor(raw)
let foreground = PerfectColor.chooseForeground(for: tamed)let (bg, fg) = PerfectColor.analyze(image: cgImage)
Text("Hello")
.foregroundStyle(fg.color)
.background(bg.color)let color = rgb.color // SwiftUI Color
let hex = rgb.hexString // "#FF5A2D"| Method | Description |
|---|---|
PerfectColor.extractDominantColor(from:) |
Extracts the dominant color via edge-weighted k-means (k=5, 64×64 downsample) |
PerfectColor.tameColor(_:maxLightness:) |
Clamps lightness for saturated colors (default max 0.45) |
PerfectColor.chooseForeground(for:) |
Returns white or black RGB based on WCAG 2.0 luminance |
PerfectColor.analyze(image:maxLightness:) |
Convenience that runs extract → tame → foreground in one call |
RGB.color |
Converts to SwiftUI Color |
RGB.hexString |
Converts to hex string (e.g. "#FF5A2D") |
- Downsample the image to 64×64 via CoreGraphics
- Weight pixels by distance from center — edge pixels get 3× weight, center pixels get 1×
- K-Means clustering (k=5, 10 iterations) groups similar colors, weighted by position
- Select the largest cluster by total weight as the dominant color
- Tame the color if it's too vivid (HSL saturation > 0.3 and lightness > 0.45)
- Choose foreground — white if background luminance ≤ 0.25, black otherwise
An example iOS app is included in Example/ChoosePerfectColorDemo/. Open the .xcodeproj in Xcode — the local package dependency is already configured.
The demo app lets you pick a photo from your library and displays the extracted background/foreground colors with smooth transitions.
MIT