ColorPerception

一个用于基于人类视觉感知分析和操作颜色的 Swift 包。该库提供了一种科学准确的方法来处理颜色,因为它会被人眼感知,而不仅仅是其原始 RGB 值。

感知亮度为何重要

人类视觉是非线性的 - 我们不会以线性方式感知光强度的变化。例如,具有 50% RGB 强度 (127,127,127) 的灰色,在我们眼中看起来比黑白之间的“中间值”要暗得多。这是因为我们的眼睛对较暗颜色的变化比对较亮颜色的变化更敏感。

此包使用 CIELAB 颜色空间的 L*(亮度)分量,该分量专门设计用于匹配人类感知。这提供了一个感知上均匀的刻度,其中

一些主要优势

例如,以下两种灰色在 RGB 值中具有相同的数学差异,但在我们眼中看起来非常不同

该库自动处理这些感知差异,确保您的颜色调整和对比度计算与用户实际看到的内容相匹配。

功能

要求

安装

Swift Package Manager

通过 Xcode 将 ColorPerception 添加到您的项目

  1. File > Add Packages...
  2. 输入包 URL:https://github.com/gregmturek/color-perception
  3. 选择“Up to Next Major Version”

或者将其添加到您的 Package.swift

dependencies: [
    .package(url: "https://github.com/gregmturek/color-perception", from: "1.0.0")
]

用法

SwiftUI

import SwiftUI
import ColorPerception

// Core perceptual properties
let sunset = Color.orange
let luminance = sunset.relativeLuminance  // Physical light measurement (0-1)
let lightness = sunset.perceivedLightness  // Human perception (0-100)
let isDark = sunset.isPerceptuallyDark  // true if lightness < 50
let isLight = sunset.isPerceptuallyLight  // true if lightness > 50

// Contrast calculations
let skyContrast = sunset.perceivedContrast(against: .cyan)  // Positive if sunset is lighter

// Finding contrasting colors
let bestContrast = sunset.perceptualContrastingColor()  // Uses cached black/white decision
let bestFromOptions = sunset.perceptualContrastingColor(from: .purple, .indigo)  // Finds highest contrast

// Adjusting lightness
let dusk = sunset.adjustingPerceivedLightness(by: -30)  // Darker sunset
let noon = sunset.adjustingPerceivedLightness(by: 30)  // Brighter sunset
let sunrise = sunset.withPerceivedLightness(85)  // Early morning glow

UIKit

import UIKit
import ColorPerception

// Core perceptual properties
let ocean = UIColor.blue
let luminance = ocean.relativeLuminance  // Physical light measurement (0-1)
let lightness = ocean.perceivedLightness  // Human perception (0-100)
let isDark = ocean.isPerceptuallyDark  // true if lightness < 50
let isLight = ocean.isPerceptuallyLight  // true if lightness > 50

// Contrast calculations
let sandContrast = ocean.perceivedContrast(against: .orange)  // Positive if ocean is lighter

// Finding contrasting colors
let bestContrast = ocean.perceptualContrastingColor()  // Uses cached black/white decision
let bestFromOptions = ocean.perceptualContrastingColor(from: .orange, .brown)  // Finds highest contrast

// Adjusting lightness
let deepOcean = ocean.adjustingPerceivedLightness(by: -40)  // Deep waters
let shallows = ocean.adjustingPerceivedLightness(by: 25)  // Tropical waters
let seafoam = ocean.withPerceivedLightness(90)  // Breaking waves

高级用法

自定义对比度缓存

对于特殊用例,您可以创建自定义缓存,其中包含您自己的深色/浅色对

// Create a custom cache
let cache = DefaultContrastPairCache<UIColor>(
    darkColor: UIColor(red: 0.0, green: 0.05, blue: 0.2, alpha: 1.0),  // Deep ocean abyss
    lightColor: UIColor(red: 0.7, green: 0.85, blue: 1.0, alpha: 1.0),  // Ocean surface
    cacheSize: 200  // Optional, defaults to 100
)

// Use custom cache for contrast decisions
let contrast = color.perceptualContrastingColor(using: cache)

默认情况下,对比度计算会自动使用高效的线程安全实现进行缓存。 缓存使用黑色和白色作为默认对比色对,并自动管理内存使用。 只有在需要不同的对比色或缓存大小的特殊情况下才需要自定义缓存。

直接颜色计算

为了获得更多控制,您可以直接使用 ColorPerceptionUtils 执行计算

// Extract and convert color components
let components = ColorPerceptionUtils.extractSRGBComponents(from: color.cgColor)
let rLinear = ColorPerceptionUtils.convertToLinearSRGB(components.red)
let gLinear = ColorPerceptionUtils.convertToLinearSRGB(components.green)
let bLinear = ColorPerceptionUtils.convertToLinearSRGB(components.blue)

// Calculate physical measurements
let luminance = ColorPerceptionUtils.calculateRelativeLuminance(
    red: components.red,
    green: components.green,
    blue: components.blue
)

// Convert to human perception
let lightness = ColorPerceptionUtils.calculatePerceivedLightness(from: luminance)

// Compare colors
let contrast = ColorPerceptionUtils.calculatePerceivedContrast(
    lhsLightness: color1.perceivedLightness,
    rhsLightness: color2.perceivedLightness
)

// Make perceptual decisions
let isLight = ColorPerceptionUtils.checkIfPerceptuallyLight(perceivedLightness: lightness)
let isDark = ColorPerceptionUtils.checkIfPerceptuallyDark(perceivedLightness: lightness)

// Change colors
let adjusted = ColorPerceptionUtils.withPerceivedLightness(color, lightness: 75)  // Set absolute lightness
let brighter = ColorPerceptionUtils.adjustPerceivedLightness(of: color, by: 20)   // Relative adjustment

// Find optimal contrast
let bestContrast = ColorPerceptionUtils.findOptimalContrastingColor(
    baseColor: color,
    from: [option1, option2, option3],
    using: cache,
    perceivedLightness: lightness
)

当您需要更多控制或想要实现自定义颜色操作算法时,这些较低级别的实用程序可让您直接访问颜色科学计算。

贡献

欢迎贡献!请随时提交 Pull Request。

许可证

本项目已获得 MIT 许可证的许可 - 有关详细信息,请参阅 LICENSE 文件。