Skip to content

Instantly share code, notes, and snippets.

@yosshi4486
Last active November 26, 2023 09:35
Show Gist options
  • Save yosshi4486/09780a2788b02d52ec3d0018cd558ed2 to your computer and use it in GitHub Desktop.
Save yosshi4486/09780a2788b02d52ec3d0018cd558ed2 to your computer and use it in GitHub Desktop.
Swift Extended sRGB Convert methods.
/// Extended Range sRGB, 拡張範囲sRGBの構造体.
///
/// ユーザーがカラーピッカーで選択した色を保存する際、
/// 拡張sRGBに変換して取り回せばDisplay P3やAdobe RGBなどRGB系の別カラースペースの場合でも気にせず取り扱え便利なため中心的に利用する.
struct ExtendedSRGB: Hashable, Codable {
/// 負数と1以上の値も扱える赤の値. 0.0~1.0はsRGBと互換性がある。
var red: CGFloat
/// 負数と1以上の値も扱える緑の値. 0.0~1.0はsRGBと互換性がある。
var green: CGFloat
/// 負数と1以上の値も扱える青の値. 0.0~1.0はsRGBと互換性がある。
var blue: CGFloat
/// 負数と1以上の値も扱える透過度の値. 0.0~1.0はsRGBと互換性がある。
var alpha: CGFloat
}
extension CGColor {
/// 拡張sRGBの値.
///
/// Core Graphicsに詳しいわけじゃないので、もしかしたらconvertメソッドがnilを返すケースもあるかもしれないので注意.
var extendedSRGB: ExtendedSRGB {
let sRGBColor = converted(to: CGColorSpace(name: CGColorSpace.extendedSRGB)!, intent: .defaultIntent, options: nil)!
return ExtendedSRGB(red: sRGBColor.components![0], green: sRGBColor.components![1], blue: sRGBColor.components![2], alpha: sRGBColor.components![3])
}
}
extension UIColor {
/// 拡張sRGBの値.
var extendedSRGB: ExtendedSRGB {
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 0.0
self.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
return ExtendedSRGB(red: red, green: green, blue: blue, alpha: alpha)
}
}
final class ExtendedSRGBTests: XCTestCase {
func testUIColorWithSRGBRange() throws {
let sRGBColor = UIColor(red: 0, green: 1, blue: 0, alpha: 1)
let rgb = sRGBColor.extendedSRGB
XCTAssertEqual(rgb.red, 0)
XCTAssertEqual(rgb.green, 1)
XCTAssertEqual(rgb.blue, 0)
XCTAssertEqual(rgb.alpha, 1)
}
func testUIColorWithDisplayP3Range() throws {
let p3Color = UIColor(displayP3Red: 0, green: 1, blue: 0, alpha: 1)
let rgb = p3Color.extendedSRGB
XCTAssertEqual(rgb.red, -0.5116420984268188)
XCTAssertEqual(rgb.green, 1.0182716846466064)
XCTAssertEqual(rgb.blue, -0.31062406301498413)
XCTAssertEqual(rgb.alpha, 1)
}
func testCGColorWithSRGBRange() throws {
let sRGBColor = CGColor(srgbRed: 0, green: 1, blue: 0, alpha: 1)
let rgb = sRGBColor.extendedSRGB
XCTAssertEqual(rgb.red, 0)
XCTAssertEqual(rgb.green, 1)
XCTAssertEqual(rgb.blue, 0)
XCTAssertEqual(rgb.alpha, 1)
}
func testCGColorWithDisplayP3Range() throws {
let p3Color = CGColor(colorSpace: CGColorSpace(name: CGColorSpace.displayP3)!, components: [0.0, 1.0, 0.0, 1.0])!
let rgb = p3Color.extendedSRGB
XCTAssertEqual(rgb.red, -0.5116420984268188)
XCTAssertEqual(rgb.green, 1.0182716846466064)
XCTAssertEqual(rgb.blue, -0.31062406301498413)
XCTAssertEqual(rgb.alpha, 1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment