{"id":25448090,"url":"https://github.com/gregmturek/color-perception","last_synced_at":"2026-02-15T04:36:13.864Z","repository":{"id":277396136,"uuid":"932291119","full_name":"gregmturek/color-perception","owner":"gregmturek","description":"A Swift package for analyzing and manipulating colors based on human visual perception.","archived":false,"fork":false,"pushed_at":"2025-03-03T21:42:56.000Z","size":24,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-20T19:22:55.879Z","etag":null,"topics":["accessibility","cielab","color","contrast","ios","lightness","package","perception","rgb","swift","swiftui","uikit"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gregmturek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-13T17:16:45.000Z","updated_at":"2025-08-31T20:18:39.000Z","dependencies_parsed_at":"2025-05-16T07:19:36.717Z","dependency_job_id":null,"html_url":"https://github.com/gregmturek/color-perception","commit_stats":null,"previous_names":["gregmturek/color-perception"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/gregmturek/color-perception","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregmturek%2Fcolor-perception","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregmturek%2Fcolor-perception/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregmturek%2Fcolor-perception/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregmturek%2Fcolor-perception/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gregmturek","download_url":"https://codeload.github.com/gregmturek/color-perception/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gregmturek%2Fcolor-perception/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29469643,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T04:35:06.950Z","status":"ssl_error","status_checked_at":"2026-02-15T04:33:41.357Z","response_time":118,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","cielab","color","contrast","ios","lightness","package","perception","rgb","swift","swiftui","uikit"],"created_at":"2025-02-17T19:18:46.738Z","updated_at":"2026-02-15T04:36:13.849Z","avatar_url":"https://github.com/gregmturek.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ColorPerception\n\nA Swift package for analyzing and manipulating colors based on human visual perception. This library provides a scientifically accurate way to work with colors as they are perceived by the human eye, rather than just their raw RGB values.\n\n## Why Perceived Lightness Matters\n\nWe don't perceive changes in light intensity in a linear way. For example, a gray color with 50% RGB intensity (127,127,127) appears much darker to our eyes than \"halfway\" between black and white. This is because our eyes are more sensitive to changes in darker colors than in lighter ones.\n\nThis package uses the CIELAB color space's L* (lightness) component, which was specifically designed to match human perception. This provides a perceptually uniform scale where:\n- 0 represents black\n- 50 represents perceptual middle gray\n- 100 represents white\n\nSome key benefits:\n\n- **Accurate Contrast**: Better accessibility by ensuring text remains readable against any background\n- **Perceptual Uniformity**: Changes in lightness appear consistent across the entire range\n- **Scientific Accuracy**: Based on the CIE 1931 color space and ITU-R BT.709 standards\n- **Color Fidelity**: Maintains original hue and, when possible, preserves saturation during lightness adjustments by using sophisticated HSB transformations\n\nFor example, these two grays have the same mathematical difference in RGB values, but appear very different to our eyes:\n- Dark grays: (10,10,10) → (20,20,20) = small perceived difference\n- Light grays: (200,200,200) → (210,210,210) = barely noticeable difference\n\nThis library handles these perceptual differences automatically, ensuring your color adjustments and contrast calculations match what users actually see.\n\n## Features\n\n* Calculating perceived lightness and relative luminance\n* Finding optimal contrasting colors\n* Adjusting colors based on perceived lightness\n* Thread-safe caching of contrast decisions\n* Support for both SwiftUI and UIKit\n* Precise color adjustments (±0.1 perceived lightness)\n\n## Requirements\n\n* iOS 15.0+\n* tvOS 15.0+\n* watchOS 8.0+\n* visionOS 1.0+\n* Swift 6.0+\n\n## Installation\n\n### Swift Package Manager\n\nAdd ColorPerception to your project through Xcode:\n1. Go to **File \u003e Add Package Dependencies...**.\n2. Search for the package URL: `https://github.com/gregmturek/color-perception`.\n3. In the **Dependency Rule** list, select **Up to Next Major Version**.\n4. Click **Add Package**.\n\nOr add it to your `Package.swift`:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/gregmturek/color-perception\", from: \"1.0.0\")\n]\n```\n\n## Demo App\n\nCheck out [ColoRoulette](https://github.com/gregmturek/coloroulette), a game built with SwiftUI to demonstrate ColorPerception in action:\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/gregmturek/coloroulette/raw/main/coloroulette-light-demo.gif\" alt=\"ColoRoulette Light Demo\" width=\"22.5%\" style=\"margin-right: 5%\"\u003e\n  \u003cimg src=\"https://github.com/gregmturek/coloroulette/raw/main/coloroulette-dark-demo.gif\" alt=\"ColoRoulette Dark Demo\" width=\"22.5%\"\u003e\n\u003c/div\u003e\n\nThe game challenges players to determine whether black or white would provide better contrast against randomly selected colors, exactly the kind of decision this library helps automate.\n\n## Usage\n\n### SwiftUI\n\n```swift\nimport SwiftUI\nimport ColorPerception\n\n// Core perceptual properties\nlet sunset = Color.orange\nlet luminance = sunset.relativeLuminance  // Physical light measurement (0-1)\nlet lightness = sunset.perceivedLightness  // Human perception (0-100)\nlet isDark = sunset.isPerceptuallyDark  // true if lightness \u003c 50\nlet isLight = sunset.isPerceptuallyLight  // true if lightness \u003e 50\n\n// Contrast calculations\nlet skyContrast = sunset.perceivedContrast(against: .cyan)  // Positive if sunset is lighter\n\n// Finding contrasting colors\nlet bestContrast = sunset.perceptualContrastingColor()  // Uses cached black/white decision\nlet bestFromOptions = sunset.perceptualContrastingColor(from: .purple, .indigo)  // Finds highest contrast\n\n// Adjusting lightness\nlet dusk = sunset.adjustingPerceivedLightness(by: -30)  // Darker sunset\nlet noon = sunset.adjustingPerceivedLightness(by: 30)  // Brighter sunset\nlet sunrise = sunset.withPerceivedLightness(85)  // Early morning glow\n```\n\n### UIKit\n\n```swift\nimport UIKit\nimport ColorPerception\n\n// Core perceptual properties\nlet ocean = UIColor.blue\nlet luminance = ocean.relativeLuminance  // Physical light measurement (0-1)\nlet lightness = ocean.perceivedLightness  // Human perception (0-100)\nlet isDark = ocean.isPerceptuallyDark  // true if lightness \u003c 50\nlet isLight = ocean.isPerceptuallyLight  // true if lightness \u003e 50\n\n// Contrast calculations\nlet sandContrast = ocean.perceivedContrast(against: .orange)  // Positive if ocean is lighter\n\n// Finding contrasting colors\nlet bestContrast = ocean.perceptualContrastingColor()  // Uses cached black/white decision\nlet bestFromOptions = ocean.perceptualContrastingColor(from: .orange, .brown)  // Finds highest contrast\n\n// Adjusting lightness\nlet deepOcean = ocean.adjustingPerceivedLightness(by: -40)  // Deep waters\nlet shallows = ocean.adjustingPerceivedLightness(by: 25)  // Tropical waters\nlet seafoam = ocean.withPerceivedLightness(90)  // Breaking waves\n```\n\n### Advanced Usage\n\n#### Custom Contrast Cache\n\nFor specialized use cases, you can create a custom cache with your own dark/light color pair:\n\n```swift\n// Create a custom cache\nlet cache = DefaultContrastPairCache\u003cUIColor\u003e(\n    darkColor: UIColor(red: 0.0, green: 0.05, blue: 0.2, alpha: 1.0),  // Deep ocean abyss\n    lightColor: UIColor(red: 0.7, green: 0.85, blue: 1.0, alpha: 1.0),  // Ocean surface\n    cacheSize: 200  // Optional, defaults to 100\n)\n\n// Use custom cache for contrast decisions\nlet contrast = color.perceptualContrastingColor(using: cache)\n```\n\nBy default, contrast calculations are automatically cached using an efficient thread-safe implementation. The cache uses black and white as the default contrast pair and automatically manages memory usage. Custom caches are only needed for special cases where different contrast colors or cache sizes are required.\n\n#### Direct Color Calculations\n\nFor more control, you can use ColorPerceptionUtils directly to perform calculations:\n\n```swift\n// Extract and convert color components\nlet components = ColorPerceptionUtils.extractSRGBComponents(from: color.cgColor)\nlet rLinear = ColorPerceptionUtils.convertToLinearSRGB(components.red)\nlet gLinear = ColorPerceptionUtils.convertToLinearSRGB(components.green)\nlet bLinear = ColorPerceptionUtils.convertToLinearSRGB(components.blue)\n\n// Calculate physical measurements\nlet luminance = ColorPerceptionUtils.calculateRelativeLuminance(\n    red: components.red,\n    green: components.green,\n    blue: components.blue\n)\n\n// Convert to human perception\nlet lightness = ColorPerceptionUtils.calculatePerceivedLightness(from: luminance)\n\n// Compare colors\nlet contrast = ColorPerceptionUtils.calculatePerceivedContrast(\n    lhsLightness: color1.perceivedLightness,\n    rhsLightness: color2.perceivedLightness\n)\n\n// Make perceptual decisions\nlet isLight = ColorPerceptionUtils.checkIfPerceptuallyLight(perceivedLightness: lightness)\nlet isDark = ColorPerceptionUtils.checkIfPerceptuallyDark(perceivedLightness: lightness)\n\n// Change colors\nlet adjusted = ColorPerceptionUtils.withPerceivedLightness(color, lightness: 75)  // Set absolute lightness\nlet brighter = ColorPerceptionUtils.adjustPerceivedLightness(of: color, by: 20)   // Relative adjustment\n\n// Find optimal contrast\nlet bestContrast = ColorPerceptionUtils.findOptimalContrastingColor(\n    baseColor: color,\n    from: [option1, option2, option3],\n    using: cache,\n    perceivedLightness: lightness\n)\n```\n\nThese lower-level utilities give you direct access to the color science calculations when you need more control or want to implement custom color manipulation algorithms.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License (see the LICENSE file for details).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregmturek%2Fcolor-perception","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgregmturek%2Fcolor-perception","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgregmturek%2Fcolor-perception/lists"}