Blog スタッフブログ

Swift システム開発

[Swift]XYZ表色系をRGB変換しUIColorを取得する

Swift

こんにちは、株式会社MIXシステム開発担当のBloomです。

早速本題[Swift]XYZ表色系をRGB変換しUIColorを取得する方法について、

お仕事の中で得た知見を共有させていただきたいと思います。

実装

XYZの値からRGB値へ変換するには下記コードを利用します。

    class func convertXYZtoRGB(x: CGFloat, y: CGFloat, z: CGFloat) -> (r: CGFloat, g: CGFloat, b: CGFloat) {
        
        let x_ = x / 100.0;
        let y_ = y / 100.0;
        let z_ = z / 100.0;
        var r: Double = 0
        var g: Double = 0
        var b: Double = 0
        
        r = x_ * (3.240970) + y_ * (-1.537383) + z_ * (-0.498611);
        g = x_ * (-0.969244) + y_ * (1.875968) + z_ * (0.041555);
        b = x_ * (0.055630) + y_ * (-0.203977) + z_ * (1.056972);
        
        r = min(1.0, max(0.0, r))
        g = min(1.0, max(0.0, g))
        b = min(1.0, max(0.0, b))
        
        r = r > 0.0031308 ? pow(r, 1.0 / 2.4) * 1.055 - 0.055 : r * 12.92;
        g = g > 0.0031308 ? pow(g, 1.0 / 2.4) * 1.055 - 0.055 : g * 12.92;
        b = b > 0.0031308 ? pow(b, 1.0 / 2.4) * 1.055 - 0.055 : b * 12.92;
        return (r, g, b)
    }

戻り値はTupleを利用しています。この関数を利用し、下記の形でUIColorのextensionを実装してください。

extension UIColor {
    class func convertXYZtoRGB(x: CGFloat, y: CGFloat, z: CGFloat) -> (r: CGFloat, g: CGFloat, b: CGFloat) {
        
        let x_ = x / 100.0
        let y_ = y / 100.0
        let z_ = z / 100.0
        var r: Double = 0
        var g: Double = 0
        var b: Double = 0
        
        r = x_ * (3.240970) + y_ * (-1.537383) + z_ * (-0.498611)
        g = x_ * (-0.969244) + y_ * (1.875968) + z_ * (0.041555)
        b = x_ * (0.055630) + y_ * (-0.203977) + z_ * (1.056972)
        
        r = min(1.0, max(0.0, r))
        g = min(1.0, max(0.0, g))
        b = min(1.0, max(0.0, b))
        
        r = r > 0.0031308 ? pow(r, 1.0 / 2.4) * 1.055 - 0.055 : r * 12.92
        g = g > 0.0031308 ? pow(g, 1.0 / 2.4) * 1.055 - 0.055 : g * 12.92
        b = b > 0.0031308 ? pow(b, 1.0 / 2.4) * 1.055 - 0.055 : b * 12.92
        return (r, g, b)
    }
    
    class func color(x: CGFloat, y: CGFloat, z: CGFloat) -> UIColor {
        let (r, g, b) = UIColor.convertXYZtoRGB(x: x, y: y, z: z)
        return UIColor(red: r, green: g, blue: b, alpha: 1.0)
    }
}

これでUIColor.color(x: y: z:)を呼び出すことでXYZ表色系の値からUIColorを生成することができます。良かったですね。

参考文献

色空間の変換(2)  RGB-XYZ 変換