protected function CaptchaImageResponse::generateImage in CAPTCHA 8
Base function for generating a image CAPTCHA.
Parameters
string $code: String code to be presented on image.
Return value
resource Image to be outputted contained $code string.
1 call to CaptchaImageResponse::generateImage()
- CaptchaImageResponse::prepare in image_captcha/
src/ Response/ CaptchaImageResponse.php - Prepares the Response before it is sent to the client.
File
- image_captcha/
src/ Response/ CaptchaImageResponse.php, line 158
Class
- CaptchaImageResponse
- Response which is returned as the captcha for image_captcha.
Namespace
Drupal\image_captcha\ResponseCode
protected function generateImage($code) {
$fonts = _image_captcha_get_enabled_fonts();
$font_size = $this->config
->get('image_captcha_font_size');
list($width, $height) = _image_captcha_image_size($code);
$image = imagecreatetruecolor($width, $height);
if (!$image) {
return FALSE;
}
// Get the background color and paint the background.
$background_rgb = $this
->hexToRGB($this->config
->get('image_captcha_background_color'));
$background_color = imagecolorallocate($image, $background_rgb[0], $background_rgb[1], $background_rgb[2]);
// Set transparency if needed.
$file_format = $this->config
->get('image_captcha_file_format');
if ($file_format == IMAGE_CAPTCHA_FILE_FORMAT_TRANSPARENT_PNG) {
imagecolortransparent($image, $background_color);
}
imagefilledrectangle($image, 0, 0, $width, $height, $background_color);
$result = $this
->printString($image, $width, $height, $fonts, $font_size, $code);
if (!$result) {
return FALSE;
}
$noise_colors = [];
for ($i = 0; $i < 20; $i++) {
$noise_colors[] = imagecolorallocate($image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255));
}
// Add additional noise.
if ($this->config
->get('image_captcha_dot_noise')) {
$this
->addDots($image, $width, $height, $noise_colors);
}
if ($this->config
->get('image_captcha_line_noise')) {
$this
->addLines($image, $width, $height, $noise_colors);
}
$distortion_amplitude = 0.25 * $font_size * $this->config
->get('image_captcha_distortion_amplitude') / 10.0;
if ($distortion_amplitude > 1) {
$wavelength_xr = (2 + 3 * lcg_value()) * $font_size;
$wavelength_yr = (2 + 3 * lcg_value()) * $font_size;
$freq_xr = 2 * 3.141592 / $wavelength_xr;
$freq_yr = 2 * 3.141592 / $wavelength_yr;
$wavelength_xt = (2 + 3 * lcg_value()) * $font_size;
$wavelength_yt = (2 + 3 * lcg_value()) * $font_size;
$freq_xt = 2 * 3.141592 / $wavelength_xt;
$freq_yt = 2 * 3.141592 / $wavelength_yt;
$distorted_image = imagecreatetruecolor($width, $height);
if ($file_format == IMAGE_CAPTCHA_FILE_FORMAT_TRANSPARENT_PNG) {
imagecolortransparent($distorted_image, $background_color);
}
if (!$distorted_image) {
return FALSE;
}
if ($this->config
->get('image_captcha_bilinear_interpolation')) {
// Distortion with bilinear interpolation.
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
// Get distorted sample point in source image.
$r = $distortion_amplitude * sin($x * $freq_xr + $y * $freq_yr);
$theta = $x * $freq_xt + $y * $freq_yt;
$sx = $x + $r * cos($theta);
$sy = $y + $r * sin($theta);
$sxf = (int) floor($sx);
$syf = (int) floor($sy);
if ($sxf < 0 || $syf < 0 || $sxf >= $width - 1 || $syf >= $height - 1) {
$color = $background_color;
}
else {
// Bilinear interpolation: sample at four corners.
$color_00 = imagecolorat($image, $sxf, $syf);
$color_00_r = $color_00 >> 16 & 0xff;
$color_00_g = $color_00 >> 8 & 0xff;
$color_00_b = $color_00 & 0xff;
$color_10 = imagecolorat($image, $sxf + 1, $syf);
$color_10_r = $color_10 >> 16 & 0xff;
$color_10_g = $color_10 >> 8 & 0xff;
$color_10_b = $color_10 & 0xff;
$color_01 = imagecolorat($image, $sxf, $syf + 1);
$color_01_r = $color_01 >> 16 & 0xff;
$color_01_g = $color_01 >> 8 & 0xff;
$color_01_b = $color_01 & 0xff;
$color_11 = imagecolorat($image, $sxf + 1, $syf + 1);
$color_11_r = $color_11 >> 16 & 0xff;
$color_11_g = $color_11 >> 8 & 0xff;
$color_11_b = $color_11 & 0xff;
// Interpolation factors.
$u = $sx - $sxf;
$v = $sy - $syf;
$r = (int) ((1 - $v) * ((1 - $u) * $color_00_r + $u * $color_10_r) + $v * ((1 - $u) * $color_01_r + $u * $color_11_r));
$g = (int) ((1 - $v) * ((1 - $u) * $color_00_g + $u * $color_10_g) + $v * ((1 - $u) * $color_01_g + $u * $color_11_g));
$b = (int) ((1 - $v) * ((1 - $u) * $color_00_b + $u * $color_10_b) + $v * ((1 - $u) * $color_01_b + $u * $color_11_b));
$color = ($r << 16) + ($g << 8) + $b;
}
imagesetpixel($distorted_image, $x, $y, $color);
}
}
}
else {
// Distortion with nearest neighbor interpolation.
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
// Get distorted sample point in source image.
$r = $distortion_amplitude * sin($x * $freq_xr + $y * $freq_yr);
$theta = $x * $freq_xt + $y * $freq_yt;
$sx = $x + $r * cos($theta);
$sy = $y + $r * sin($theta);
$sxf = (int) floor($sx);
$syf = (int) floor($sy);
if ($sxf < 0 || $syf < 0 || $sxf >= $width - 1 || $syf >= $height - 1) {
$color = $background_color;
}
else {
$color = imagecolorat($image, $sxf, $syf);
}
imagesetpixel($distorted_image, $x, $y, $color);
}
}
}
imagedestroy($image);
return $distorted_image;
}
else {
return $image;
}
}