用PHP+GD扩展实现图像高斯模糊处理

很久以前写的代码了,现在才想起贴上来. 稍微更改并结合人脸识别可以实现自动模糊人物的脸部.

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
157
158
159
160
161
162
163
164
165
166
167
168
169
<?php
require_once 'RGB.php'; //这里请看另一个 "PHP实现色彩空间转换"
/**
 * 图像信息处理
 * @author shizhuolin
 */
class Image {
 
    /**
     * 位图资源
     * @var resource 
     */
    protected $_image;
 
    /**
     * 使用指定文件构造图像操作实例
     * @param string $filename 
     */
    public function __construct($filename=null) {
        if ($filename)
            $this->open($filename);
    }
 
    /**
     * 读取指定文件明的图像
     * @param string $filename
     * @return Image 
     */
    public function open($filename) {
        $handle = fopen($filename, "rb");
        $contents = stream_get_contents($handle);
        fclose($handle);
        $image = imagecreatefromstring($contents);
        $width = imagesx($image);
        $height = imagesy($image);
        $truecolorimage = imagecreatetruecolor($width, $height);
        imagefilledrectangle($truecolorimage, 0, 0, $width, $height, 0xFFFFFF);
        imagecopyresampled($truecolorimage, $image, 0, 0, 0, 0, $width, $height, $width, $height);
        imagedestroy($image);
        $this->setImage($truecolorimage);
        return $this;
    }
 
    /**
     * 读取指定资源的图像
     * @param resource $image
     * @return Image 
     */
    public function load($image) {
        $width = imagesx($image);
        $height = imagesy($image);
        $truecolorimage = imagecreatetruecolor($width, $height);
        imagefilledrectangle($truecolorimage, 0, 0, $width, $height, 0xFFFFFF);
        imagecopyresampled($truecolorimage, $image, 0, 0, 0, 0, $width, $height, $width, $height);
        if ($this->getImage()) {
            imagedestroy($this->getImage());
        }
        $this->setImage($truecolorimage);
        return $this;
    }
 
    /**
     * 设置内部图像资源描述符
     * @param resource $image 
     */
    protected function setImage($image) {
        $this->_image = $image;
    }
 
    /**
     * 获取内部操作图像资源
     * @return resource 
     */
    public function getImage() {
        return $this->_image;
    }
 
    /**
     * 获取图像宽度
     * @return int
     */
    public function getWidth() {
        return imagesx($this->getImage());
    }
 
    /**
     * 获取图像高度
     * @return int
     */
    public function getHeight() {
        return imagesy($this->getImage());
    }
 
    /**
     * 获取指定坐标像素颜色
     * @param type $x
     * @param type $y
     * @return type 
     */
    public function getColorAt($x, $y) {
        $rgb = imageColorAt($this->getImage(), $x, $y);
        $r = ($rgb >> 16) & 0xFF;
        $g = ($rgb >> 8) & 0xFF;
        $b = $rgb & 0xFF;
        return array('red' => $r, 'green' => $g, 'blue' => $b);
    }
 
    /**
     * 高斯模糊(单纬度二次模糊)
     * @param float $radius 半径
     */
    public function gaussianBlur($radius=1.0) {
        $width = $this->getWidth();
        $height = $this->getHeight();
        $sigma = $radius / 3;
        $sigma2 = 2 * pow($sigma, 2);
        $matrix = array();
        $newimage = imagecreatetruecolor($width, $height);
        /* 生成高斯矩阵(单纬度矩阵) */
        for ($x = -$radius; $x <= $radius; $x++) {
            $x2 = pow($x, 2) + pow($x, 2);
            $matrix[] = exp(-$x2 / $sigma2) / ($sigma2 * M_PI);
        }
        /* 构建模糊图像 */
        for ($y = 0; $y < $height; $y++) {
            for ($x = 0; $x < $width; $x++) {
                $bright = $red = $green = $blue = 0;
                /* 垂直模糊 */
                for ($yy = -$radius; $yy <= $radius; $yy++) {
                    $yyy = $y + $yy;
                    if ($yyy >= 0 && $yyy < $height) {
                        $weight = $matrix[$yy + $radius];
                        $bright += $weight;
                        $color = $this->getColorAt($x, $yyy);
                        $red += ($color['red'] * $weight);
                        $green += ($color['green'] * $weight);
                        $blue += ($color['blue'] * $weight);
                    }
                }
                /* 水平模糊 */
                for ($xx = -$radius; $xx <= $radius; $xx++) {
                    $xxx = $x + $xx;
                    if ($xxx >= 0 && $xxx < $width && $xx != 0) {
                        $weight = $matrix[$xx + $radius];
                        $bright+=$weight;
                        $color = $this->getColorAt($xxx, $y);
                        $red += ($color['red'] * $weight);
                        $green += ($color['green'] * $weight);
                        $blue += ($color['blue'] * $weight);
                    }
                }
                $z = 1 / $bright;
                imagesetpixel($newimage, $x, $y, ($red * $z << 16) | ($green * $z << 8) | $blue * $z);
            }
        }
        imagedestroy($this->getImage());
        $this->setImage($newimage);
    }
 
    /**
     * 析构 销毁图像占用内存
     */
    public function __destruct() {
        if ($this->getImage()) {
            imagedestroy($this->getImage());
        }
    }
 
}

调用代码

1
2
3
4
5
6
<?php
require_once 'Image.php';
$image = new Image("http://www.u-cola.com/images/200809/1220676617582974754.jpg");
$image->gaussianBlur(10);
header("Content-type: image/png");
imagepng($image->getImage());

Leave a Reply

Your email address will not be published.

Time limit is exhausted. Please reload the CAPTCHA.

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