function DrawSquared() { // This will tell us if lines have already begun to be drawn. // It is an array to keep separate information for every line, for with a single // variable we could sometimes get "undefined offset" errors and no plot... $start_lines = array_fill(0, $this->records_per_group, FALSE); if ($this->data_type == 'text-data') { $lastx[0] = $this->xtr(0); $lasty[0] = $this->xtr(0); } for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { $record = 1; // Skip record #0 (data label) if ($this->data_type == 'data-data') { // Do we have a value for X? $x_now = $this->data[$row][$record++]; } else { $x_now = 0.5 + $cnt++; } // Place text-data at X = 0.5, 1.5, 2.5, etc... $x_now_pixels = $this->xtr($x_now); // Absolute coordinates if ($this->x_data_label_pos != 'none') { // Draw X Data labels? $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); } // notice there is no last param. // Draw Lines for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data $y_now_pixels = $this->ytr($this->data[$row][$record]); if ($start_lines[$idx] == TRUE) { // Set line width, revert it to normal at the end ImageSetThickness($this->img, $this->line_widths[$idx]); if ($this->line_styles[$idx] == 'dashed') { $this->SetDashedStyle($this->ndx_data_colors[$idx]); ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx], IMG_COLOR_STYLED); ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels, IMG_COLOR_STYLED); } else { ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx], $this->ndx_data_colors[$idx]); ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels, $this->ndx_data_colors[$idx]); } } $lastx[$idx] = $x_now_pixels; $lasty[$idx] = $y_now_pixels; $start_lines[$idx] = TRUE; } else { if ($this->draw_broken_lines) { $start_lines[$idx] = FALSE; } } } } // end while ImageSetThickness($this->img, 1); }
/** * Gets the line style of the element * @return int A GD linestyle representing the line style * @see Image_Graph_Line * @access private */ function _getLineStyle() { $this->_debug("Getting line style"); if (is_numeric($this->_lineStyle)) { if (isset($GLOBALS['_Image_Graph_gd2'])) { ImageSetThickness($this->_canvas(), 1); } return $this->_color($this->_lineStyle); } elseif ($this->_lineStyle != null) { if (is_a($this->_lineStyle, "Image_Graph_Color")) { ImageSetThickness($this->_canvas(), 1); return $this->_lineStyle->_index; } else { return $this->_lineStyle->_getLineStyle(); } } else { if (isset($GLOBALS['_Image_Graph_gd2'])) { ImageSetThickness($this->_canvas(), 1); } return $this->_color(IMAGE_GRAPH_BLACK); } }
protected function DrawSquared() { if (!$this->CheckDataType('text-data, data-data')) { return FALSE; } // Flag array telling if the current point is valid, one element per plot line. // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point. $start_lines = array_fill(0, $this->records_per_group, FALSE); for ($row = 0, $cnt = 0; $row < $this->num_data_rows; $row++) { $record = 1; // Skip record #0 (data label) if ($this->data_type == 'data-data') { // Do we have a value for X? $x_now = $this->data[$row][$record++]; } else { $x_now = 0.5 + $cnt++; } // Place text-data at X = 0.5, 1.5, 2.5, etc... $x_now_pixels = $this->xtr($x_now); // Absolute coordinates if ($this->x_data_label_pos != 'none') { // Draw X Data labels? $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels); } // notice there is no last param. // Draw Lines for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { if (is_numeric($this->data[$row][$record])) { // Allow for missing Y data $y_now_pixels = $this->ytr($this->data[$row][$record]); if ($start_lines[$idx] == TRUE) { // Set line width, revert it to normal at the end ImageSetThickness($this->img, $this->line_widths[$idx]); if ($this->line_styles[$idx] == 'dashed') { $this->SetDashedStyle($this->ndx_data_colors[$idx]); ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx], IMG_COLOR_STYLED); ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels, IMG_COLOR_STYLED); } else { ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx], $this->ndx_data_colors[$idx]); ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels, $this->ndx_data_colors[$idx]); } } $lastx[$idx] = $x_now_pixels; $lasty[$idx] = $y_now_pixels; $start_lines[$idx] = TRUE; } else { if ($this->draw_broken_lines) { $start_lines[$idx] = FALSE; } } } } // end while ImageSetThickness($this->img, 1); return TRUE; }
/** * Resets the canvas. * * Include fillstyle, linestyle, thickness and polygon * @access private */ function _reset() { if ($this->_gd2) { ImageSetThickness($this->_canvas, 1); } if ($this->_tileImage != null) { ImageDestroy($this->_tileImage); $this->_tileImage = null; } parent::_reset(); $this->_font = array('font' => 1, 'color' => 'black'); }
protected function DrawSquared() { if (!$this->CheckDataType('text-data, data-data')) { return FALSE; } // Flag array telling if the current point is valid, one element per plot line. // If start_lines[i] is true, then (lastx[i], lasty[i]) is the previous point. if ($this->data_columns > 0) { $start_lines = array_fill(0, $this->data_columns, FALSE); } $gcvars = array(); // For GetDataColor, which initializes and uses this. // Data Value Labels? $do_dvls = $this->CheckDataValueLabels($this->y_data_label_pos, $dvl); for ($row = 0; $row < $this->num_data_rows; $row++) { $record = 1; // Skip record #0 (data label) if ($this->datatype_implied) { // Implied X values? $x_now = 0.5 + $row; } else { $x_now = $this->data[$row][$record++]; } // Read it, advance record index $x_now_pixels = $this->xtr($x_now); // Absolute coordinates if ($this->x_data_label_pos != 'none') { // Draw X Data labels? $this->DrawXDataLabel($this->data[$row][0], $x_now_pixels, $row); } // Draw Lines for ($idx = 0; $record < $this->num_recs[$row]; $record++, $idx++) { if (is_numeric($y_now = $this->data[$row][$record])) { // Allow for missing Y data $y_now_pixels = $this->ytr($y_now); if ($start_lines[$idx]) { // Set line width, revert it to normal at the end ImageSetThickness($this->img, $this->line_widths[$idx]); // Select the color: $this->GetDataColor($row, $idx, $gcvars, $data_color); // Select solid color or dashed line $style = $this->SetDashedStyle($data_color, $this->line_styles[$idx] == 'dashed'); // Draw the step ImageLine($this->img, $lastx[$idx], $lasty[$idx], $x_now_pixels, $lasty[$idx], $style); ImageLine($this->img, $x_now_pixels, $lasty[$idx], $x_now_pixels, $y_now_pixels, $style); } // Draw data value labels? if ($do_dvls) { $this->DrawDataValueLabel('y', $row, $idx, $x_now, $y_now, $y_now, $dvl); } $lastx[$idx] = $x_now_pixels; $lasty[$idx] = $y_now_pixels; $start_lines[$idx] = TRUE; } elseif ($this->draw_broken_lines) { // Y data missing, leave a gap. $start_lines[$idx] = FALSE; } } } ImageSetThickness($this->img, 1); return TRUE; }
function ImageBorder() { if (isset($this->bw)) { // optional image border and fixed-dimension images (regardless of aspect ratio) $this->config_background_hexcolor = !empty($this->bg) ? $this->bg : $this->config_background_hexcolor; $this->config_border_hexcolor = !empty($this->bc) ? $this->bc : $this->config_border_hexcolor; if (!eregi('^[0-9A-F]{6}$', $this->config_background_hexcolor)) { $this->ErrorImage('Invalid hex color string "' . $this->config_background_hexcolor . '" for parameter "bg"'); } if (!eregi('^[0-9A-F]{6}$', $this->config_border_hexcolor)) { $this->ErrorImage('Invalid hex color string "' . $this->config_border_hexcolor . '" for parameter "bc"'); } $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor); $border_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_border_hexcolor); ImageFilledRectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color); if ($this->bw > 0) { // ImageRectangle() draws a rectangle centred on the coordinates given, // so coordinates must be offset by half the line thickness if ($this->bw > 1 && @ImageSetThickness($this->gdimg_output, $this->bw)) { // better way (for lines > 1px thick), but requires GD v2.0.1+ ImageRectangle($this->gdimg_output, floor($this->bw / 2), floor($this->bw / 2), $this->thumbnail_width - ceil($this->bw / 2), $this->thumbnail_height - ceil($this->bw / 2), $border_color); } else { for ($i = 0; $i < $this->bw; $i++) { ImageRectangle($this->gdimg_output, $i, $i, $this->thumbnail_width - $i - 1, $this->thumbnail_height - $i - 1, $border_color); } } } if (!empty($this->brx) && !empty($this->bry) && $this->bw > 0) { // if 'bw' > 0 then leave the image rectangular and have a rounded border line around the edges of the image // if 'bw' == 0 then round off the corners of the image itself (see RoundedImageCorners()) ImageFilledRectangle($this->gdimg_output, 0, 0, $this->brx, $this->bry, $background_color); ImageFilledRectangle($this->gdimg_output, $this->thumbnail_width - $this->brx, 0, $this->thumbnail_width, $this->bry, $background_color); ImageFilledRectangle($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->thumbnail_height - $this->bry, $this->thumbnail_width, $this->thumbnail_height, $background_color); ImageFilledRectangle($this->gdimg_output, 0, $this->thumbnail_height - $this->bry, $this->brx, $this->thumbnail_height, $background_color); // PHP bug: ImageArc() with thicknesses > 1 give bad/undesirable/unpredicatable results // Solution: Draw multiple 1px arcs side-by-side. if (phpthumb_functions::gd_version(false) >= 2) { // imagesetthickness(): requires GD 2.0 or later // GD1 always has line thickness of 1 ImageSetThickness($this->gdimg_output, 1); } for ($thickness_offset = 0; $thickness_offset < $this->bw; $thickness_offset++) { // Problem: parallel arcs give strange/ugly antialiasing problems // Solution: draw non-parallel arcs, from one side of the line thickness at the start angle // to the opposite edge of the line thickness at the terminating angle if ($this->bw > 1) { ImageArc($this->gdimg_output, $this->brx, $thickness_offset - 1 + $this->bry, $this->brx * 2, $this->bry * 2, 180, 270, $border_color); // top-left ImageArc($this->gdimg_output, $thickness_offset - 1 + $this->brx, $this->bry, $this->brx * 2, $this->bry * 2, 180, 270, $border_color); // top-left ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $thickness_offset - 1 + $this->bry, $this->brx * 2, $this->bry * 2, 270, 360, $border_color); // top-right ImageArc($this->gdimg_output, $this->thumbnail_width - $thickness_offset - $this->brx, $this->bry, $this->brx * 2, $this->bry * 2, 270, 360, $border_color); // top-right ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->thumbnail_height - $thickness_offset - $this->bry, $this->brx * 2, $this->bry * 2, 0, 90, $border_color); // bottom-right ImageArc($this->gdimg_output, $this->thumbnail_width - $thickness_offset - $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 0, 90, $border_color); // bottom-right ImageArc($this->gdimg_output, $this->brx, $this->thumbnail_height - $thickness_offset - $this->bry, $this->brx * 2, $this->bry * 2, 90, 180, $border_color); // bottom-left ImageArc($this->gdimg_output, $thickness_offset - 1 + $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 90, 180, $border_color); // bottom-left } else { ImageArc($this->gdimg_output, $this->brx, $thickness_offset + $this->bry, $this->brx * 2, $this->bry * 2, 180, 270, $border_color); // top-left ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->bry, $this->brx * 2, $this->bry * 2, 270, 360, $border_color); // top-right ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 0, 90, $border_color); // bottom-right ImageArc($this->gdimg_output, $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 90, 180, $border_color); // bottom-left } } ImageArc($this->gdimg_output, $this->brx, $this->bry, $this->brx * 2, $this->bry * 2, 180, 270, $border_color); ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->bry, $this->brx * 2, $this->bry * 2, 270, 360, $border_color); ImageArc($this->gdimg_output, $this->thumbnail_width - $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 0, 90, $border_color); ImageArc($this->gdimg_output, $this->brx, $this->thumbnail_height - $this->bry, $this->brx * 2, $this->bry * 2, 90, 180, $border_color); } } return true; }
} // draw grid on y for ($i = $rand_func(6, 20); $i < $height * 2; $i += $rand_func(10, 25)) { ImageSetThickness($temp_bg, $rand_func(2, 6)); $text_r = $rand_func(100, 150); $text_g = $rand_func(100, 150); $text_b = $rand_func(100, 150); $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); ImageLine($temp_bg, 0, $i, $width * 2, $i, $text_colour3); } } else { if ($bg_type == 2) { // draw squiggles! $bg3 = ImageColorAllocate($im3, 255, 255, 255); ImageFill($im3, 0, 0, $bg3); ImageSetThickness($temp_bg, 4); for ($i = 0; $i < strlen($word) + 1; $i++) { $text_r = $rand_func(100, 150); $text_g = $rand_func(100, 150); $text_b = $rand_func(100, 150); $text_colour3 = ImageColorAllocate($temp_bg, $text_r, $text_g, $text_b); $points = array(); // draw random squiggle for each character // the longer the loop, the more complex the squiggle // keep random so OCR can't say "if found shape has 10 points, ignore it" // each squiggle will, however, be a closed shape, so OCR could try to find // line terminations and start from there. (I don't think they're that advanced yet..) for ($j = 1; $j < $rand_func(5, 10); $j++) { $points[] = $rand_func(1 * (20 * ($i + 1)), 1 * (50 * ($i + 1))); $points[] = $rand_func(30, $height + 30); }
$polygon = array_merge($polygon, $quad); for ($i = 2; $i < $n - 5; $i += 2) { //ctxx.bezierCurveTo(cp[2*i-2],cp[2*i-1],cp[2*i],cp[2*i+1],pts[i+2],pts[i+3]); $p1 = array($pts[$i], $pts[$i + 1]); $p2 = array($cp[2 * $i - 2], $cp[2 * $i - 1]); $p3 = array($cp[2 * $i], $cp[2 * $i + 1]); $p4 = array($pts[$i + 2], $pts[$i + 3]); $bez = Bezier_convert($p1, $p2, $p3, $p4, $t); $polygon = array_merge($polygon, $bez); } //ctxx.quadraticCurveTo(cp[2*n-10],cp[2*n-9],pts[n-2],pts[n-1]); // last arc $quad = quadBezier($polygon[count($polygon) - 2], $polygon[count($polygon) - 1], $cp[2 * $n - 10], $cp[2 * $n - 9], $pts[$n - 2], $pts[$n - 1]); $polygon = array_merge($polygon, $quad); } return $polygon; } $p = drawSpline(array(50, 250, 550, 250, 550, 750)); //print_r($p); exit; $img = imagecreatetruecolor(80, 80); $img2 = imagecreatetruecolor(800, 800); $bg = ImageColorAllocate($img2, 255, 255, 255); $fg = ImageColorAllocate($img2, 0, 0, 0); imagefill($img2, 0, 0, $bg); imageantialias($img2, true); ImageSetThickness($img2, 5); ImagePolygon($img2, $p, count($p) / 2, $fg); imagearc($img2, 400, 400, 200, 200, 0, 350, $fg); for ($i = 0; $i < 0; $i++) { imagefilter($img2, IMG_FILTER_GAUSSIAN_BLUR); } ImagePng($img2);
ImageSetThickness($im, mt_rand(1, 2)); ImageLine($im, $vx, $vy, $ux, $uy, $linecolor); $vx = $ux; $vy = $uy; } ImageLine($im, $vx, $vy, $x, $y2, $linecolor); // Triangle ImageSetThickness($im, 3); $ux = mt_rand($x2 - 10, $x2 + 10); $uy = mt_rand($y2 - 10, $y2 - 30); ImageLine($im, mt_rand(10, $x2 - 20), $y, $ux, $uy, $linecolor); ImageSetThickness($im, 1); ImageLine($im, mt_rand($x2 + 20, $x - 10), $y, $ux, $uy, $linecolor); ImageSetThickness($im, 1); // Border ImageSetThickness($im, 1); ImageLine($im, 0, 0, 0, $y, $bordercolor); // left ImageLine($im, 0, 0, $x, 0, $bordercolor); // top ImageLine($im, 0, $y - 1, $x, $y - 1, $bordercolor); // bottom ImageLine($im, $x - 1, 0, $x - 1, $y - 1, $bordercolor); // right for ($i = $x / $clen; $i < $x; $i += $x / $clen) { ImageLine($im, $i, 0, $i, $y, $bordercolor); } switch ($c_imgtype) { case 'jpeg': Header("Content-Type: image/jpeg"); ImageJPEG($im, "", 75);
/** * Gets the line style of the element * @return int A GD linestyle representing the line style * @see Image_Graph_Line * @access private */ function _getLineStyle() { if (isset($GLOBALS['_Image_Graph_gd2'])) { ImageSetThickness($this->_canvas(), $this->_thickness); } return $this->_color->_index; }
function _drawxaxis() { $maxlabwid = $this->_maxlab(); $x0 = $this->lm; $y0 = $this->tm + $this->cheight; $x1 = $x0 + $this->cwidth; $y1 = $y0; $div = $this->xgridint; imageline($this->image,$x0,$y0,$x1,$y1,$this->gridcol); $gry = $this->xgrid ? $this->tm : $this->tm + $this->cheight + 3 ; $ii=0; for ($x=$x1,$i=$this->xcount-1; $x>$x0+3; $x -= $div, $i--, $ii++) { if ($this->xdashed) { for ($xd=$gry;$xd<=$y0; $xd=$xd+4) { imagesetpixel($this->image,$x,$xd,$this->gridcol); } } else { imageline($this->image,$x,$gry,$x,$y0,$this->gridcol); } imageline($this->image,$x,$y0-4,$x,$y0+3,$this->txtcol); $v = $this->xlabels[$i]; $tw = strlen("$v")*imagefontwidth(2); $th = imagefontheight(2); if (!($ii%$this->xstep)) { if ($this->xdelta) { if (!$delta) { $delta=12; } else { $delta=0; } } else { $delta=0; } $this->_writestring($this->image,2,$x - ($div+$tw)/2, $y0 + 5 + $delta, $v, $this->txtcol,0,0); } } $y = $this->height - 30; $tw = strlen($this->xtitle)*imagefontwidth(3); $x = ($this->lm + $this->cwidth + $this->lm - $tw)/2; $this->_writestring($this->image,3,$this->lm + $this->cwidth+2,$y0-20,$this->xtitle,$this->txtcol,1,0); if ($this->xstr) { $points[0] = $this->lm + $this->cwidth+10; $points[1] = $y0-3; $points[2] = $points[0]+15; $points[3] = $points[1]+3; $points[4] = $points[2]-15; $points[5] = $points[3]+3; $points[6] = $points[4]+3; $points[7] = $points[5]-3; ImageSetThickness($this->image, $this->xline); imageline($this->image,$x0,$y0,$x1+15,$y1,$this->txtcol); ImageSetThickness($this->image, 1); ImageFilledPolygon($this->image,$points,4,$this->txtcol); } }
/** * Generate noisy background * * @param int $width: width of the image in pixels * @param int $height: width of the image in pixels * @param string $word: the captcha word * @param string $backgroundType (see constants) * @param array $backgroundImages: array of background image file names * @param boolean $morphBackground: if TRUE, the background will be morphed * @param boolean $blurBackground: if TRUE, the background will be blurred * @return string GD image identifier of noisy background */ public static function generateNoisyBackground($width, $height, $word, $backgroundType, $backgroundImages = array(), $morphBackground = TRUE, $blurBackground = TRUE) { $image = ImageCreateTrueColor($width, $height); if ($backgroundType != self::BACKGROUND_TYPE_TRANSPARENT) { // Generate noisy background, to be merged with CAPTCHA later // any suggestions on how best to do this much appreciated // sample code would be even better! // I'm not an OCR expert (hell, I'm not even an image expert; puremango.co.uk was designed in MsPaint) // so the noise models are based around my -guesswork- as to what would make it hard for an OCR prog // ideally, the character obfuscation would be strong enough not to need additional background noise // in any case, I hope at least one of the options given here provide some extra security! $tempBackground = ImageCreateTrueColor($width * 1.5, $height * 1.5); $background = ImageColorAllocate($image, 255, 255, 255); ImageFill($image, 0, 0, $background); $tempBackgroundColor = ImageColorAllocate($tempBackground, 255, 255, 255); ImageFill($tempBackground, 0, 0, $tempBackgroundColor); // We draw all noise onto tempBackground // then if we're morphing, merge from tempBackground to image // or if not, just copy a $width x $height portion of $tempBackground to $image // tempBackground is much larger so that when morphing, the edges retain the noise. switch ($backgroundType) { case self::BACKGROUND_TYPE_WHITE_WITH_GRID: // Draw grid on x for ($i = RandomContentUtility::getRandomNumberInRange(6, 20); $i < $width * 2; $i += RandomContentUtility::getRandomNumberInRange(10, 25)) { ImageSetThickness($tempBackground, RandomContentUtility::getRandomNumberInRange(2, 6)); $textColor = RandomContentUtility::getRandomColor(100, 150); $textColor2 = ImageColorAllocate($tempBackground, $textColor[0], $textColor[1], $textColor[2]); ImageLine($tempBackground, $i, 0, $i, $height * 2, $textColor2); } // Draw grid on y for ($i = RandomContentUtility::getRandomNumberInRange(6, 20); $i < $height * 2; $i += RandomContentUtility::getRandomNumberInRange(10, 25)) { ImageSetThickness($tempBackground, RandomContentUtility::getRandomNumberInRange(2, 6)); $textColor = RandomContentUtility::getRandomColor(100, 150); $textColor2 = ImageColorAllocate($tempBackground, $textColor[0], $textColor[1], $textColor[2]); ImageLine($tempBackground, 0, $i, $width * 2, $i, $textColor2); } break; case self::BACKGROUND_TYPE_WHITE_WITH_SQUIGGLES: ImageSetThickness($tempBackground, 4); for ($i = 0; $i < strlen($word) + 1; $i++) { $textColor = RandomContentUtility::getRandomColor(100, 150); $textColor2 = ImageColorAllocate($tempBackground, $textColor[0], $textColor[1], $textColor[2]); $points = array(); // Draw random squiggle for each character // the longer the loop, the more complex the squiggle // keep random so OCR can't say "if found shape has 10 points, ignore it" // each squiggle will, however, be a closed shape, so OCR could try to find // line terminations and start from there. (I don't think they're that advanced yet..) for ($j = 1; $j < RandomContentUtility::getRandomNumberInRange(5, 10); $j++) { $points[] = RandomContentUtility::getRandomNumberInRange(1 * (20 * ($i + 1)), 1 * (50 * ($i + 1))); $points[] = RandomContentUtility::getRandomNumberInRange(30, $height + 30); } ImagePolygon($tempBackground, $points, intval(sizeof($points) / 2), $textColor2); } break; case self::BACKGROUND_TYPE_MORPHED_IMAGE_BLOCKS: // Take random chunks of $backgroundImages and paste them onto the background for ($i = 0; $i < sizeof($backgroundImages); $i++) { // Read each image and its size $tempImages[$i] = ImageCreateFromJPEG(GeneralUtility::getFileAbsFileName($backgroundImages[$i])); $tempWidths[$i] = imagesx($tempImages[$i]); $tempHeights[$i] = imagesy($tempImages[$i]); } $blocksize = RandomContentUtility::getRandomNumberInRange(20, 60); for ($i = 0; $i < $width * 2; $i += $blocksize) { // Could randomise blocksize here... hardly matters for ($j = 0; $j < $height * 2; $j += $blocksize) { $imageIndex = RandomContentUtility::getRandomNumberInRange(0, sizeof($tempImages) - 1); $cut_x = RandomContentUtility::getRandomNumberInRange(0, $tempWidths[$imageIndex] - $blocksize); $cut_y = RandomContentUtility::getRandomNumberInRange(0, $tempHeights[$imageIndex] - $blocksize); ImageCopy($tempBackground, $tempImages[$imageIndex], $i, $j, $cut_x, $cut_y, $blocksize, $blocksize); } } // Cleanup for ($i = 0; $i < sizeof($tempImages); $i++) { ImageDestroy($tempImages[$i]); } break; } if ($morphBackground) { // Morph background // We do this separately to the main text morph because: // a) the main text morph is done char-by-char, this is done across whole image // b) if an attacker could un-morph the background, it would un-morph the CAPTCHA // hence background is morphed differently to text // why do we morph it at all? it might make it harder for an attacker to remove the background // morph_chunk 1 looks better but takes longer // this is a different and less perfect morph than the one we do on the CAPTCHA // occasonally you get some dark background showing through around the edges // it doesn't need to be perfect as it's only the background. $morph_chunk = RandomContentUtility::getRandomNumberInRange(1, 5); $morph_y = 0; for ($x = 0; $x < $width; $x += $morph_chunk) { $morph_chunk = RandomContentUtility::getRandomNumberInRange(1, 5); $morph_y += RandomContentUtility::getRandomNumberInRange(-1, 1); ImageCopy($image, $tempBackground, $x, 0, $x + 30, 30 + $morph_y, $morph_chunk, $height * 2); } ImageCopy($tempBackground, $image, 0, 0, 0, 0, $width, $height); $morph_x = 0; for ($y = 0; $y <= $height; $y += $morph_chunk) { $morph_chunk = RandomContentUtility::getRandomNumberInRange(1, 5); $morph_x += RandomContentUtility::getRandomNumberInRange(-1, 1); ImageCopy($image, $tempBackground, $morph_x, $y, 0, $y, $width, $morph_chunk); } } else { // Just copy tempBackground onto $image ImageCopy($image, $tempBackground, 0, 0, 30, 30, $width, $height); } // Cleanup ImageDestroy($tempBackground); if ($blurBackground) { $image = self::blurImage($image); } } return $image; }