PHP实现RGB,HSL,HSV色彩空间转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
 
/**
 * HSL色彩空间描述
 * @author shizhuolin
 */
class HSL {
 
    /**
     * 色相 0-360
     * @var float 
     */
    protected $_hue;
 
    /**
     * 饱和度 0-1
     * @var float 
     */
    protected $_saturation;
 
    /**
     * 亮度 0-1
     * @var float 
     */
    protected $_lightness;
 
    /**
     * 构造HSL色彩空间描述
     * @param float $hue
     * @param float $saturation
     * @param float $lightness 
     */
    public function __construct($hue=0, $saturation=0, $lightness=0) {
        $this->_hue = $hue;
        $this->_saturation = $saturation;
        $this->_lightness = $lightness;
    }
 
    /**
     * 获取色相
     * @return float 
     */
    public function getHue() {
        return $this->_hue;
    }
 
    /**
     * 获取饱和度
     * @return float 
     */
    public function getSaturation() {
        return $this->_saturation;
    }
 
    /**
     * 获取亮度
     * @return float 
     */
    public function getLightness() {
        return $this->_lightness;
    }
 
    /**
     * 获取RGB形式色彩空间描述
     * @return RGB 
     */
    public function toRGB() {
        $h = $this->getHue();
        $s = $this->getSaturation();
        $l = $this->getLightness();
 
        if ($s == 0) {
            require_once 'RGB.php';
            return new RGB($l, $l, $l);
        }
 
        $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - ($l * $s);
        $p = 2 * $l - $q;
        $hk = $h / 360;
        $tR = $hk + (1 / 3);
        $tG = $hk;
        $tB = $hk - (1 / 3);
 
        $tR = $this->getTC($tR);
        $tG = $this->getTC($tG);
        $tB = $this->getTC($tB);
        $tR = $this->getColorC($tR, $p, $q);
        $tG = $this->getColorC($tG, $p, $q);
        $tB = $this->getColorC($tB, $p, $q);
 
        require_once 'RGB.php';
        return new RGB($tR, $tG, $tB);
    }
 
    private function getColorC($tc, $p, $q) {
        if ($tc < (1 / 6)) {
            return $p + (($q - $p) * 6 * $tc );
        } else if ((1 / 6) <= $tc && $tc < 0.5) {
            return $q;
        } else if (0.5 <= $tc && $tc < (2 / 3)) {
            return $p + (($q - $p) * 6 * (2 / 3 - $tc) );
        } else {
            return $p;
        }
    }
 
    private function getTC($c) {
        if ($c < 0)
            $c++;
        if ($c > 1)
            $c--;
        return $c;
    }
 
    /**
     * 获取 array形式HSL色彩描述
     * @return array 
     */
    public function toArray() {
        return array(
            'hue' => $this->getHue(),
            'saturation' => $this->getSaturation(),
            'lightness' => $this->getLightness()
        );
    }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<?php
 
/**
 * HSV色彩空间描述
 * @author shizhuolin
 */
class HSV {
 
    /**
     * 色相 0-260
     * @var float 
     */
    protected $_hue;
 
    /**
     * 饱和度 0-1
     * @var float 
     */
    protected $_saturation;
 
    /**
     * 色调 0-1
     * @var float 
     */
    protected $_value;
 
    /**
     * 构造
     * @param float $hue 色相
     * @param float $saturation 饱和度
     * @param float $value 色调
     */
    public function __construct($hue=0, $saturation=0, $value=0) {
        $this->_hue = $hue;
        $this->_saturation = $saturation;
        $this->_value = $value;
    }
 
    /**
     * 获取色相 0-360
     * @return float 
     */
    public function getHue() {
        return $this->_hue;
    }
 
    /**
     * 获取饱和度 0-1
     * @return float 
     */
    public function getSaturation() {
        return $this->_saturation;
    }
 
    /**
     * 获取色调 0-1
     * @return float 
     */
    public function getValue() {
        return $this->_value;
    }
 
    /**
     * 返回该色彩在RGB色彩空间的描述
     * @return RGB
     */
    public function toRGB() {
        $hue = $this->getHue();
        $saturation = $this->getSaturation();
        $value = $this->getValue();
        $hi = floor($hue / 60) % 6;
        $f = $hue / 60 - $hi;
        $p = $value * (1 - $saturation);
        $q = $value * (1 - $f * $saturation);
        $t = $value * (1 - (1 - $f) * $saturation);
        switch ($hi) {
            case 0:
                $red = $value;
                $green = $t;
                $blue = $p;
                break;
            case 1:
                $red = $q;
                $green = $value;
                $blue = $p;
                break;
            case 2:
                $red = $p;
                $green = $value;
                $blue = $t;
                break;
            case 3:
                $red = $p;
                $green = $q;
                $blue = $value;
                break;
            case 4:
                $red = $t;
                $green = $p;
                $blue = $value;
                break;
            case 5:
                $red = $value;
                $green = $p;
                $blue = $q;
                break;
            default:
                throw new ErrorException('HSV Conversion RGB failure!');
                break;
        };
        require_once 'RGB.php';
        return new RGB($red, $green, $blue);
    }
 
    /**
     * 返回数组形式表达
     * @return array
     */
    public function toArray() {
        return array(
            'hue' => $this->getHue(),
            'saturation' => $this->getSaturation(),
            'value' => $this->getValue()
        );
    }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
 
/**
 * RGB色彩空间描述
 * @author shizhuolin
 */
class RGB {
 
    /**
     * 红色 0-1
     * @var float 
     */
    protected $_red;
 
    /**
     * 绿色 0-1
     * @var float 
     */
    protected $_green;
 
    /**
     * 蓝色 0-1
     * @var float 
     */
    protected $_blue;
 
    /**
     * 以初始值构造
     * @param float $red 红色0-1
     * @param float $green 绿色0-1
     * @param float $blue 蓝色0-1
     */
    public function __construct($red = 0, $green = 0, $blue = 0) {
        $this->_red = $red;
        $this->_green = $green;
        $this->_blue = $blue;
    }
 
    /**
     * 获取红色分量
     * @return float
     */
    public function getRed() {
        return $this->_red;
    }
 
    /**
     * 获取绿色分量
     * @return float 
     */
    public function getGreen() {
        return $this->_green;
    }
 
    /**
     * 获取蓝色分量
     * @return float 
     */
    public function getBlue() {
        return $this->_blue;
    }
 
    /**
     * 返回该色彩的HSL空间描述
     * @return HSL
     */
    public function toHSL() {
        $r = $this->getRed();
        $g = $this->getGreen();
        $b = $this->getBlue();
        $rgb = array($r, $g, $b);
        $max = max($rgb);
        $min = min($rgb);
        $diff = $max - $min;
        if ($max == $min) {
            $h = 0;
        } else if ($max == $r && $g >= $b) {
            $h = 60 * (($g - $b) / $diff);
        } else if ($max == $r && $g < $b) {
            $h = 60 * (($g - $b) / $diff) + 360;
        } else if ($max == $g) {
            $h = 60 * (($b - $r) / $diff) + 120;
        } else if ($max == $b) {
            $h = 60 * (($r - $g) / $diff) + 240;
        } else {
            throw new ErrorException("RGB conversion HSL failure!");
        }
        $l = ($max + $min) / 2;
        if ($l == 0 || $max == $min) {
            $s = 0;
        } else if (0 < $l && $l <= 0.5) {
            $s = $diff / (2 * $l);
        } else if ($l > 0.5) {
            $s = $diff / (2 - 2 * $l);
        } else {
            throw new ErrorException("RGB conversion HSL failure!");
        }
        require_once 'HSL.php';
        return new HSL($h, $s, $l);
    }
 
    /**
     * 返回此色彩的HSV空间描述
     * @return HSV 
     */
    public function toHSV() {
        $red = $this->getRed();
        $green = $this->getGreen();
        $blue = $this->getBlue();
 
        $rgb = array($red, $green, $blue);
        $max = max($rgb);
        $min = min($rgb);
        $diff = $max - $min;
 
        /* 计算色相 */
        if ($max == $min) {
            $hue = 0;
        } else if ($max == $red && $green >= $blue) {
            $hue = 60 * (($green - $blue) / $diff);
        } else if ($max == $red && $green < $blue) {
            $hue = 60 * (($green - $blue) / $diff) + 360;
        } else if ($max == $green) {
            $hue = 60 * (($blue - $red) / $diff) + 120;
        } else if ($max == $blue) {
            $hue = 60 * (($red - $green) / $diff) + 240;
        } else {
            throw new ErrorException("compute hue failure!");
        }
 
        /* 计算饱和度 */
        if ($max == 0) {
            $saturation = 0;
        } else {
            $saturation = 1 - $min / $max;
        }
 
        /* 计算色调 */
        $value = $max;
 
        require_once 'HSV.php';
        return new HSV($hue, $saturation, $value);
    }
 
    /**
     * 返回该色彩的数组表现形式
     */
    public function toArray() {
        return array(
            'red' => $this->getRed(),
            'green' => $this->getGreen(),
            'blue' => $this->getBlue()
        );
    }
 
}

效果测试(需要phpunit支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
 
require_once dirname(__FILE__) . '/../../color/RGB.php';
require_once dirname(__FILE__) . '/../../color/HSL.php';
require_once dirname(__FILE__) . '/../../color/HSV.php';
 
/**
 * Test class for HSL.
 * Generated by PHPUnit on 2011-11-29 at 16:56:17.
 */
class HSLTest extends PHPUnit_Framework_TestCase {
 
    /**
     * @var HSL
     */
    protected $object;
 
    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp() {
        $this->object = new HSL(120, 1, 0.75);
    }
 
    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown() {
 
    }
 
    /**
     * @todo Implement testGetHue().
     */
    public function testGetHue() {
        $this->assertEquals(120, $this->object->getHue());
    }
 
    /**
     * @todo Implement testGetSaturation().
     */
    public function testGetSaturation() {
        $this->assertEquals(1, $this->object->getSaturation());
    }
 
    /**
     * @todo Implement testGetLightness().
     */
    public function testGetLightness() {
        $this->assertEquals(0.75, $this->object->getLightness());
    }
 
    /**
     * @todo Implement testToRGB().
     */
    public function testToRGB() {
        $this->assertEquals(new RGB(0.5, 1, 0.5), $this->object->toRGB());
    }
 
    /**
     * @todo Implement testToArray().
     */
    public function testToArray() {
        $this->assertEquals(array(
            'hue' => 120,
            'saturation' => 1,
            'lightness' => 0.75
                ), $this->object->toArray());
    }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
 
require_once dirname(__FILE__) . '/../../color/RGB.php';
require_once dirname(__FILE__) . '/../../color/HSL.php';
require_once dirname(__FILE__) . '/../../color/HSV.php';
 
/**
 * Test class for HSV.
 * Generated by PHPUnit on 2011-11-29 at 16:49:00.
 */
class HSVTest extends PHPUnit_Framework_TestCase {
 
    /**
     * @var HSV
     */
    protected $object;
 
    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp() {
        $this->object = new HSV(120, 0.5, 1);
    }
 
    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown() {
 
    }
 
    /**
     * @todo Implement testGetHue().
     */
    public function testGetHue() {
        $this->assertEquals(120, $this->object->getHue());
    }
 
    /**
     * @todo Implement testGetSaturation().
     */
    public function testGetSaturation() {
        $this->assertEquals(0.5, $this->object->getSaturation());
    }
 
    /**
     * @todo Implement testGetValue().
     */
    public function testGetValue() {
        $this->assertEquals(1, $this->object->getValue());
    }
 
    /**
     * @todo Implement testToRGB().
     */
    public function testToRGB() {
        $this->assertEquals(new RGB(0.5, 1, 0.5), $this->object->toRGB());
    }
 
    /**
     * @todo Implement testToArray().
     */
    public function testToArray() {
        $this->assertEquals(array(
            'hue' => 120,
            'saturation' => 0.5,
            'value' => 1
                ), $this->object->toArray());
    }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
 
require_once dirname(__FILE__) . '/../../color/RGB.php';
require_once dirname(__FILE__) . '/../../color/HSL.php';
require_once dirname(__FILE__) . '/../../color/HSV.php';
 
/**
 * Test class for RGB.
 * Generated by PHPUnit on 2011-11-29 at 16:38:54.
 */
class RGBTest extends PHPUnit_Framework_TestCase {
 
    /**
     * @var RGB
     */
    protected $object;
 
    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp() {
        $this->object = new RGB(0.5, 1, 0.5);
    }
 
    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown() {
 
    }
 
    /**
     * @todo Implement testGetRed().
     */
    public function testGetRed() {
        $this->assertEquals(0.5, $this->object->getRed());
    }
 
    /**
     * @todo Implement testGetGreen().
     */
    public function testGetGreen() {
        $this->assertEquals(1, $this->object->getGreen());
    }
 
    /**
     * @todo Implement testGetBlue().
     */
    public function testGetBlue() {
        $this->assertEquals(0.5, $this->object->getBlue());
    }
 
    /**
     * @todo Implement testToHSL().
     */
    public function testToHSL() {
        $this->assertEquals(new HSL(120, 1, 0.75), $this->object->toHSL());
    }
 
    /**
     * @todo Implement testToHSV().
     */
    public function testToHSV() {
        $this->assertEquals(new HSV(120, 0.5, 1), $this->object->toHSV());
    }
 
    /**
     * @todo Implement testToArray().
     */
    public function testToArray() {
        $this->assertEquals(array(
            'red' => 0.5,
            'green' => 1,
            'blue' => 0.5
                ), $this->object->toArray());
    }
 
}

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com