Révision ac1bc5de
Ajouté par Assos Assos il y a plus de 9 ans
drupal7/sites/all/modules/captcha/image_captcha/image_captcha.user.inc | ||
---|---|---|
12 | 12 |
* Menu callback function that generates the CAPTCHA image. |
13 | 13 |
*/ |
14 | 14 |
function image_captcha_image() { |
15 |
// If output buffering is on: discard current content and disable further buffering |
|
15 |
// If output buffering is on: discard current content and disable further buffering.
|
|
16 | 16 |
if (ob_get_level()) { |
17 | 17 |
ob_end_clean(); |
18 | 18 |
} |
19 | 19 |
|
20 |
if (!isset($_GET['sid'])) { |
|
20 |
if (!isset($_GET['sid']) || is_array($_GET['sid'])) {
|
|
21 | 21 |
exit(); |
22 | 22 |
} |
23 | 23 |
$captcha_sid = $_GET['sid']; |
... | ... | |
34 | 34 |
$seed = hexdec(substr(md5($captcha_sid . $code), 0, 8)); |
35 | 35 |
srand($seed); |
36 | 36 |
mt_srand($seed); |
37 |
// generate the image
|
|
37 |
// Generate the image.
|
|
38 | 38 |
$image = @_image_captcha_generate_image($code); |
39 |
// check of generation was successful
|
|
39 |
// Check of generation was successful.
|
|
40 | 40 |
if (!$image) { |
41 | 41 |
watchdog('CAPTCHA', 'Generation of image CAPTCHA failed. Check your image CAPTCHA configuration and especially the used font.', array(), WATCHDOG_ERROR); |
42 | 42 |
exit(); |
... | ... | |
57 | 57 |
exit(); |
58 | 58 |
} |
59 | 59 |
|
60 |
|
|
61 | 60 |
/** |
62 | 61 |
* Small helper function for parsing a hexadecimal color to a RGB tuple. |
63 | 62 |
*/ |
64 | 63 |
function _image_captcha_hex_to_rgb($hex) { |
65 |
// handle #RGB format
|
|
64 |
// Handle #RGB format/
|
|
66 | 65 |
if (strlen($hex) == 4) { |
67 | 66 |
$hex = $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3]; |
68 | 67 |
} |
... | ... | |
74 | 73 |
return $rgb; |
75 | 74 |
} |
76 | 75 |
|
77 |
|
|
78 | 76 |
/** |
79 | 77 |
* Base function for generating a image CAPTCHA. |
80 | 78 |
*/ |
... | ... | |
82 | 80 |
// Get font. |
83 | 81 |
$fonts = _image_captcha_get_enabled_fonts(); |
84 | 82 |
|
85 |
// get other settings
|
|
83 |
// Get other settings.
|
|
86 | 84 |
$font_size = (int) variable_get('image_captcha_font_size', 30); |
87 | 85 |
list($width, $height) = _image_captcha_image_size($code); |
88 | 86 |
|
89 |
// create image resource
|
|
87 |
// Create image resource.
|
|
90 | 88 |
$image = imagecreatetruecolor($width, $height); |
91 | 89 |
if (!$image) { |
92 | 90 |
return FALSE; |
... | ... | |
106 | 104 |
global $language; |
107 | 105 |
$rtl = $language->direction && ((bool) variable_get('image_captcha_rtl_support', 0)); |
108 | 106 |
|
109 |
// draw text
|
|
107 |
// Draw text.
|
|
110 | 108 |
$result = _image_captcha_image_generator_print_string($image, $width, $height, $fonts, $font_size, $code, $rtl); |
111 | 109 |
if (!$result) { |
112 | 110 |
return FALSE; |
113 | 111 |
} |
114 | 112 |
|
115 |
// add noise
|
|
113 |
// Add noise.
|
|
116 | 114 |
$noise_colors = array(); |
117 | 115 |
for ($i = 0; $i < 20; $i++) { |
118 | 116 |
$noise_colors[] = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255)); |
... | ... | |
128 | 126 |
// Distort the image. |
129 | 127 |
$distortion_amplitude = .25 * $font_size * variable_get('image_captcha_distortion_amplitude', 0) / 10.0; |
130 | 128 |
if ($distortion_amplitude > 1) { |
131 |
// distortion parameters
|
|
129 |
// Distortion parameters.
|
|
132 | 130 |
$wavelength_xr = (2 + 3 * mt_rand(0, 1000) / 1000) * $font_size; |
133 | 131 |
$wavelength_yr = (2 + 3 * mt_rand(0, 1000) / 1000) * $font_size; |
134 | 132 |
$freq_xr = 2 * 3.141592 / $wavelength_xr; |
... | ... | |
147 | 145 |
} |
148 | 146 |
|
149 | 147 |
if (variable_get('image_captcha_bilinear_interpolation', FALSE)) { |
150 |
// distortion with bilinear interpolation
|
|
148 |
// Distortion with bilinear interpolation.
|
|
151 | 149 |
for ($x = 0; $x < $width; $x++) { |
152 | 150 |
for ($y = 0; $y < $height; $y++) { |
153 |
// get distorted sample point in source image
|
|
151 |
// Get distorted sample point in source image.
|
|
154 | 152 |
$r = $distortion_amplitude * sin($x * $freq_xr + $y * $freq_yr); |
155 | 153 |
$theta = $x * $freq_xt + $y * $freq_yt; |
156 | 154 |
$sx = $x + $r * cos($theta); |
157 | 155 |
$sy = $y + $r * sin($theta); |
158 |
$sxf = (int)floor($sx); |
|
159 |
$syf = (int)floor($sy); |
|
156 |
$sxf = (int) floor($sx);
|
|
157 |
$syf = (int) floor($sy);
|
|
160 | 158 |
if ($sxf < 0 || $syf < 0 || $sxf >= $width - 1 || $syf >= $height - 1) { |
161 | 159 |
$color = $background_color; |
162 | 160 |
} |
163 | 161 |
else { |
164 |
// bilinear interpolation: sample at four corners
|
|
165 |
$color_00 = imagecolorat($image, $sxf , $syf );
|
|
162 |
// Bilinear interpolation: sample at four corners.
|
|
163 |
$color_00 = imagecolorat($image, $sxf, $syf);
|
|
166 | 164 |
$color_00_r = ($color_00 >> 16) & 0xFF; |
167 | 165 |
$color_00_g = ($color_00 >> 8) & 0xFF; |
168 | 166 |
$color_00_b = $color_00 & 0xFF; |
169 |
$color_10 = imagecolorat($image, $sxf+1, $syf );
|
|
167 |
$color_10 = imagecolorat($image, $sxf + 1, $syf);
|
|
170 | 168 |
$color_10_r = ($color_10 >> 16) & 0xFF; |
171 | 169 |
$color_10_g = ($color_10 >> 8) & 0xFF; |
172 | 170 |
$color_10_b = $color_10 & 0xFF; |
173 |
$color_01 = imagecolorat($image, $sxf , $syf+1);
|
|
171 |
$color_01 = imagecolorat($image, $sxf, $syf + 1);
|
|
174 | 172 |
$color_01_r = ($color_01 >> 16) & 0xFF; |
175 | 173 |
$color_01_g = ($color_01 >> 8) & 0xFF; |
176 | 174 |
$color_01_b = $color_01 & 0xFF; |
177 |
$color_11 = imagecolorat($image, $sxf+1, $syf+1);
|
|
175 |
$color_11 = imagecolorat($image, $sxf + 1, $syf + 1);
|
|
178 | 176 |
$color_11_r = ($color_11 >> 16) & 0xFF; |
179 | 177 |
$color_11_g = ($color_11 >> 8) & 0xFF; |
180 | 178 |
$color_11_b = $color_11 & 0xFF; |
181 |
// interpolation factors
|
|
179 |
// Interpolation factors.
|
|
182 | 180 |
$u = $sx - $sxf; |
183 | 181 |
$v = $sy - $syf; |
184 |
// interpolate
|
|
185 |
$r = (int)((1-$v)*((1-$u)*$color_00_r + $u*$color_10_r) + $v*((1-$u)*$color_01_r + $u*$color_11_r));
|
|
186 |
$g = (int)((1-$v)*((1-$u)*$color_00_g + $u*$color_10_g) + $v*((1-$u)*$color_01_g + $u*$color_11_g));
|
|
187 |
$b = (int)((1-$v)*((1-$u)*$color_00_b + $u*$color_10_b) + $v*((1-$u)*$color_01_b + $u*$color_11_b));
|
|
188 |
// build color
|
|
182 |
// Interpolate.
|
|
183 |
$r = (int) ((1 - $v) * ((1 - $u) * $color_00_r + $u * $color_10_r) + $v * ((1 - $u) * $color_01_r + $u * $color_11_r));
|
|
184 |
$g = (int) ((1 - $v) * ((1 - $u) * $color_00_g + $u * $color_10_g) + $v * ((1 - $u) * $color_01_g + $u * $color_11_g));
|
|
185 |
$b = (int) ((1 - $v) * ((1 - $u) * $color_00_b + $u * $color_10_b) + $v * ((1 - $u) * $color_01_b + $u * $color_11_b));
|
|
186 |
// Build color.
|
|
189 | 187 |
$color = ($r<<16) + ($g<<8) + $b; |
190 | 188 |
} |
191 | 189 |
imagesetpixel($distorted_image, $x, $y, $color); |
... | ... | |
193 | 191 |
} |
194 | 192 |
} |
195 | 193 |
else { |
196 |
// distortion with nearest neighbor interpolation
|
|
194 |
// Distortion with nearest neighbor interpolation.
|
|
197 | 195 |
for ($x = 0; $x < $width; $x++) { |
198 | 196 |
for ($y = 0; $y < $height; $y++) { |
199 |
// get distorted sample point in source image
|
|
197 |
// Get distorted sample point in source image.
|
|
200 | 198 |
$r = $distortion_amplitude * sin($x * $freq_xr + $y * $freq_yr); |
201 | 199 |
$theta = $x * $freq_xt + $y * $freq_yt; |
202 | 200 |
$sx = $x + $r * cos($theta); |
203 | 201 |
$sy = $y + $r * sin($theta); |
204 |
$sxf = (int)floor($sx); |
|
205 |
$syf = (int)floor($sy); |
|
202 |
$sxf = (int) floor($sx);
|
|
203 |
$syf = (int) floor($sy);
|
|
206 | 204 |
if ($sxf < 0 || $syf < 0 || $sxf >= $width - 1 || $syf >= $height - 1) { |
207 | 205 |
$color = $background_color; |
208 | 206 |
} |
... | ... | |
213 | 211 |
} |
214 | 212 |
} |
215 | 213 |
} |
216 |
// release undistorted image
|
|
214 |
// Release undistorted image.
|
|
217 | 215 |
imagedestroy($image); |
218 |
// return distorted image
|
|
216 |
// Return distorted image.
|
|
219 | 217 |
return $distorted_image; |
220 | 218 |
} |
221 | 219 |
else { |
... | ... | |
223 | 221 |
} |
224 | 222 |
} |
225 | 223 |
|
224 |
/** |
|
225 |
* Add lines. |
|
226 |
*/ |
|
226 | 227 |
function _image_captcha_image_generator_add_lines(&$image, $width, $height, $colors) { |
227 |
$line_quantity = $width * $height/200.0 * ((int) variable_get('image_captcha_noise_level', 5)) / 10.0;
|
|
228 |
for ($i = 0; $i < $line_quantity; $i++) {
|
|
228 |
$line_quantity = $width * $height / 200.0 * ((int) variable_get('image_captcha_noise_level', 5)) / 10.0;
|
|
229 |
for ($i = 0; $i < $line_quantity; $i++) { |
|
229 | 230 |
imageline($image, mt_rand(0, $width), mt_rand(0, $height), mt_rand(0, $width), mt_rand(0, $height), $colors[array_rand($colors)]); |
230 | 231 |
} |
231 | 232 |
} |
232 | 233 |
|
234 |
/** |
|
235 |
* Add dots. |
|
236 |
*/ |
|
233 | 237 |
function _image_captcha_image_generator_add_dots(&$image, $width, $height, $colors) { |
234 | 238 |
$noise_quantity = $width * $height * ((int) variable_get('image_captcha_noise_level', 5)) / 10.0; |
235 |
for ($i = 0; $i < $noise_quantity; $i++ ) {
|
|
239 |
for ($i = 0; $i < $noise_quantity; $i++) { |
|
236 | 240 |
imagesetpixel($image, mt_rand(0, $width), mt_rand(0, $height), $colors[array_rand($colors)]); |
237 | 241 |
} |
238 | 242 |
} |
... | ... | |
240 | 244 |
/** |
241 | 245 |
* Helper function for drawing text on the image. |
242 | 246 |
*/ |
243 |
function _image_captcha_image_generator_print_string(&$image, $width, $height, $fonts, $font_size, $text, $rtl=FALSE) {
|
|
244 |
// get characters
|
|
247 |
function _image_captcha_image_generator_print_string(&$image, $width, $height, $fonts, $font_size, $text, $rtl = FALSE) {
|
|
248 |
// Get characters.
|
|
245 | 249 |
$characters = _image_captcha_utf8_split($text); |
246 | 250 |
$character_quantity = count($characters); |
247 | 251 |
|
248 |
// get colors
|
|
252 |
// Get colors.
|
|
249 | 253 |
$background_rgb = _image_captcha_hex_to_rgb(variable_get('image_captcha_background_color', '#ffffff')); |
250 | 254 |
$foreground_rgb = _image_captcha_hex_to_rgb(variable_get('image_captcha_foreground_color', '#000000')); |
251 | 255 |
$background_color = imagecolorallocate($image, $background_rgb[0], $background_rgb[1], $background_rgb[2]); |
252 | 256 |
$foreground_color = imagecolorallocate($image, $foreground_rgb[0], $foreground_rgb[1], $foreground_rgb[2]); |
253 |
// precalculate the value ranges for color randomness
|
|
254 |
$foreground_randomness = (int)(variable_get('image_captcha_foreground_color_randomness', 100)); |
|
257 |
// Precalculate the value ranges for color randomness.
|
|
258 |
$foreground_randomness = (int) (variable_get('image_captcha_foreground_color_randomness', 100));
|
|
255 | 259 |
if ($foreground_randomness) { |
256 | 260 |
$foreground_color_range = array(); |
257 |
for ($i=0; $i<3; $i++) { |
|
258 |
$foreground_color_range[$i] = array(max(0, $foreground_rgb[$i] - $foreground_randomness), min(255, $foreground_rgb[$i] + $foreground_randomness)); |
|
261 |
for ($i = 0; $i < 3; $i++) { |
|
262 |
$foreground_color_range[$i] = array( |
|
263 |
max(0, $foreground_rgb[$i] - $foreground_randomness), |
|
264 |
min(255, $foreground_rgb[$i] + $foreground_randomness), |
|
265 |
); |
|
259 | 266 |
} |
260 | 267 |
} |
261 | 268 |
|
262 |
// set default text color
|
|
269 |
// Set default text color.
|
|
263 | 270 |
$color = $foreground_color; |
264 | 271 |
|
265 |
// the image is seperated in different character cages, one for each character
|
|
266 |
// each character will be somewhere inside that cage |
|
272 |
// The image is seperated in different character cages, one for each character,
|
|
273 |
// each character will be somewhere inside that cage.
|
|
267 | 274 |
$ccage_width = $width / $character_quantity; |
268 | 275 |
$ccage_height = $height; |
269 | 276 |
|
270 | 277 |
foreach ($characters as $c => $character) { |
271 |
// initial position of character: in the center of its cage
|
|
278 |
// Initial position of character: in the center of its cage.
|
|
272 | 279 |
$center_x = ($c + 0.5) * $ccage_width; |
273 | 280 |
if ($rtl) { |
274 | 281 |
$center_x = $width - $center_x; |
... | ... | |
294 | 301 |
else { |
295 | 302 |
$character_width = imagefontwidth(5); |
296 | 303 |
$character_height = imagefontheight(5); |
297 |
$bbox = array(0, $character_height, $character_width, $character_height, $character_width, 0, 0, 0); |
|
304 |
$bbox = array( |
|
305 |
0, |
|
306 |
$character_height, |
|
307 |
$character_width, |
|
308 |
$character_height, |
|
309 |
$character_width, |
|
310 |
0, |
|
311 |
0, |
|
312 |
0, |
|
313 |
); |
|
298 | 314 |
} |
299 | 315 |
|
300 | 316 |
// Random (but small) rotation of the character. |
... | ... | |
305 | 321 |
// printed so that the bounding box would be nicely centered in the cage? |
306 | 322 |
$bb_center_x = .5 * ($bbox[0] + $bbox[2]); |
307 | 323 |
$bb_center_y = .5 * ($bbox[1] + $bbox[7]); |
308 |
$angle_cos = cos($angle*3.1415/180);
|
|
309 |
$angle_sin = sin($angle*3.1415/180);
|
|
324 |
$angle_cos = cos($angle * 3.1415 / 180);
|
|
325 |
$angle_sin = sin($angle * 3.1415 / 180);
|
|
310 | 326 |
$pos_x = $center_x - ($angle_cos * $bb_center_x + $angle_sin * $bb_center_y); |
311 | 327 |
$pos_y = $center_y - (-$angle_sin * $bb_center_x + $angle_cos * $bb_center_y); |
312 | 328 |
|
... | ... | |
317 | 333 |
$dev_x = .5 * max(0, $ccage_width - abs($angle_cos) * $bb_width - abs($angle_sin) * $bb_height); |
318 | 334 |
$dev_y = .5 * max(0, $ccage_height - abs($angle_cos) * $bb_height - abs($angle_sin) * $bb_width); |
319 | 335 |
|
320 |
// add jitter to position
|
|
336 |
// Add jitter to position.
|
|
321 | 337 |
$pos_x = $pos_x + mt_rand(-$dev_x, $dev_x); |
322 | 338 |
$pos_y = $pos_y + mt_rand(-$dev_y, $dev_y); |
323 | 339 |
|
324 |
// calculate text color in case of randomness
|
|
340 |
// Calculate text color in case of randomness.
|
|
325 | 341 |
if ($foreground_randomness) { |
326 | 342 |
$color = imagecolorallocate($image, |
327 | 343 |
mt_rand($foreground_color_range[0][0], $foreground_color_range[0][1]), |
... | ... | |
330 | 346 |
); |
331 | 347 |
} |
332 | 348 |
|
333 |
// draw character
|
|
349 |
// Draw character.
|
|
334 | 350 |
if ($font == 'BUILTIN') { |
335 | 351 |
imagestring($image, 5, $pos_x, $pos_y, $character, $color); |
336 | 352 |
} |
... | ... | |
340 | 356 |
|
341 | 357 |
// For debugging purposes: draw character bounding box (only valid when rotation is disabled). |
342 | 358 |
// imagerectangle($image, $pos_x + $bbox[0], $pos_y + $bbox[1], $pos_x + $bbox[2], $pos_y + $bbox[7], $color); |
343 |
|
|
344 | 359 |
} |
345 | 360 |
|
346 |
// return a sign of success
|
|
361 |
// Return a sign of success.
|
|
347 | 362 |
return TRUE; |
348 | 363 |
} |
Formats disponibles : Unified diff
Weekly update of contrib modules