function area($x_start, $y_start, $x_end, $y_end, $type, $colour, $offset) { //dbug("drawing area type: $type, at offset: $offset"); if ($this->parameter['zero_axis'] != 'none') { $bottom = $this->calculated['boundary_box']['bottom']; $zero = $this->calculated['zero_axis']; if ($this->parameter['shadow_below_axis']) { $zero += $offset; } $u_start = $x_start + $offset; $u_end = $x_end + $offset; $v_start = $bottom - $y_start + $offset; $v_end = $bottom - $y_end + $offset; switch ($type) { case 'fill': // draw it this way 'cos the FilledPolygon routine seems a bit buggy. ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]); ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]); break; case 'open': //ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $zero, $u_start, $zero), 4, $this->colour[$colour]); ImageLine($this->image, $u_start, $v_start, $u_end, $v_end, $this->colour[$colour]); ImageLine($this->image, $u_start, $v_start, $u_start, $zero, $this->colour[$colour]); ImageLine($this->image, $u_end, $v_end, $u_end, $zero, $this->colour[$colour]); break; } } else { $bottom = $this->calculated['boundary_box']['bottom']; $u_start = $x_start + $offset; $u_end = $x_end + $offset; $v_start = $bottom - $y_start + $offset; $v_end = $bottom - $y_end + $offset; if ($this->parameter['shadow_below_axis']) { $bottom += $offset; } if ($this->parameter['inner_border'] != 'none') { $bottom -= 1; } // 1 pixel above bottom if border is to be drawn. switch ($type) { case 'fill': ImageFilledPolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]); break; case 'open': ImagePolygon($this->image, array($u_start, $v_start, $u_end, $v_end, $u_end, $bottom, $u_start, $bottom), 4, $this->colour[$colour]); break; } } }
protected function DrawDot($x_world, $y_world, $record, $color) { $index = $record % $this->point_counts; $point_size = $this->point_sizes[$index]; $half_point = (int) ($point_size / 2); $x_mid = $this->xtr($x_world); $y_mid = $this->ytr($y_world); $x1 = $x_mid - $half_point; $x2 = $x_mid + $half_point; $y1 = $y_mid - $half_point; $y2 = $y_mid + $half_point; switch ($this->point_shapes[$index]) { case 'halfline': ImageLine($this->img, $x1, $y_mid, $x_mid, $y_mid, $color); break; case 'line': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); break; case 'plus': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); break; case 'cross': ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'circle': ImageArc($this->img, $x_mid, $y_mid, $point_size, $point_size, 0, 360, $color); break; case 'dot': ImageFilledEllipse($this->img, $x_mid, $y_mid, $point_size, $point_size, $color); break; case 'diamond': $arrpoints = array($x1, $y_mid, $x_mid, $y1, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'triangle': $arrpoints = array($x1, $y_mid, $x2, $y_mid, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'trianglemid': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'yield': $arrpoints = array($x1, $y1, $x2, $y1, $x_mid, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'delta': $arrpoints = array($x1, $y2, $x2, $y2, $x_mid, $y1); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'star': ImageLine($this->img, $x1, $y_mid, $x2, $y_mid, $color); ImageLine($this->img, $x_mid, $y1, $x_mid, $y2, $color); ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'hourglass': $arrpoints = array($x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'bowtie': $arrpoints = array($x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'target': ImageFilledRectangle($this->img, $x1, $y1, $x_mid, $y_mid, $color); ImageFilledRectangle($this->img, $x_mid, $y_mid, $x2, $y2, $color); ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'box': ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */ $arrpoints = array($x1, $y2, $x2, $y2, $x2, $y_mid, $x_mid, $y1, $x1, $y_mid); ImageFilledPolygon($this->img, $arrpoints, 5, $color); break; case 'up': ImagePolygon($this->img, array($x_mid, $y1, $x2, $y2, $x1, $y2), 3, $color); break; case 'down': ImagePolygon($this->img, array($x_mid, $y2, $x1, $y1, $x2, $y1), 3, $color); break; case 'none': /* Special case, no point shape here */ break; default: /* Also 'rect' */ ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; } return TRUE; }
/** * Draw a pie slice * * Parameter array: * * 'x': int X center point * * 'y': int Y center point * * 'rx': int X radius * * 'ry': int Y radius * * 'v1': int The starting angle (in degrees) * * 'v2': int The end angle (in degrees) * * 'srx': int [optional] Starting X-radius of the pie slice (i.e. for a doughnut) * * 'sry': int [optional] Starting Y-radius of the pie slice (i.e. for a doughnut) * * 'fill': mixed [optional] The fill color * * 'line': mixed [optional] The line color * * @param array $params Parameter array */ function pieslice($params) { $x = $this->_getX($params['x']); $y = $this->_getY($params['y']); $rx = $params['rx']; $ry = $params['ry']; $v1 = $params['v1']; $v2 = $params['v2']; $srx = isset($params['srx']) ? $params['srx'] : 0; $sry = isset($params['sry']) ? $params['sry'] : 0; $fillColor = isset($params['fill']) ? $params['fill'] : false; $lineColor = isset($params['line']) ? $params['line'] : false; $dA = 0.1; if ($srx !== false && $sry !== false) { $angle = max($v1, $v2); while ($angle >= min($v1, $v2)) { $polygon[] = $x + $srx * cos(deg2rad($angle % 360)); $polygon[] = $y + $sry * sin(deg2rad($angle % 360)); $angle -= $dA; } if ($angle + $dA > min($v1, $v2)) { $polygon[] = $x + $srx * cos(deg2rad(min($v1, $v2) % 360)); $polygon[] = $y + $sry * sin(deg2rad(min($v1, $v2) % 360)); } } else { $polygon[] = $x; $polygon[] = $y; } $angle = min($v1, $v2); while ($angle <= max($v1, $v2)) { $polygon[] = $x + $rx * cos(deg2rad($angle % 360)); $polygon[] = $y + $ry * sin(deg2rad($angle % 360)); $angle += $dA; } if ($angle - $dA < max($v1, $v2)) { $polygon[] = $x + $rx * cos(deg2rad(max($v1, $v2) % 360)); $polygon[] = $y + $ry * sin(deg2rad(max($v1, $v2) % 360)); } if (($fill = $this->_getFillStyle($fillColor, $x - $rx - 1, $y - $ry - 1, $x + $rx + 1, $y + $ry + 1)) !== false && count($polygon) > 2) { ImageFilledPolygon($this->_canvas, $polygon, count($polygon) / 2, $fill); } if (($line = $this->_getLineStyle($lineColor)) !== false) { ImagePolygon($this->_canvas, $polygon, count($polygon) / 2, $line); } parent::pieSlice($params); }
protected function DrawShape($x, $y, $record, $color, $allow_none = TRUE) { $index = $record % $this->point_counts; $point_size = $this->point_sizes[$index]; $half_point = (int) ($point_size / 2); $x1 = $x - $half_point; $x2 = $x + $half_point; $y1 = $y - $half_point; $y2 = $y + $half_point; switch ($this->point_shapes[$index]) { case 'halfline': ImageLine($this->img, $x1, $y, $x, $y, $color); break; case 'none': /* Special case, no point shape here */ if ($allow_none) { break; } // But fall throught to line if a shape is required // But fall throught to line if a shape is required case 'line': ImageLine($this->img, $x1, $y, $x2, $y, $color); break; case 'plus': ImageLine($this->img, $x1, $y, $x2, $y, $color); ImageLine($this->img, $x, $y1, $x, $y2, $color); break; case 'cross': ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'circle': ImageArc($this->img, $x, $y, $point_size, $point_size, 0, 360, $color); break; case 'dot': ImageFilledEllipse($this->img, $x, $y, $point_size, $point_size, $color); break; case 'diamond': $arrpoints = array($x1, $y, $x, $y1, $x2, $y, $x, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'triangle': $arrpoints = array($x1, $y, $x2, $y, $x, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'trianglemid': $arrpoints = array($x1, $y1, $x2, $y1, $x, $y); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'yield': $arrpoints = array($x1, $y1, $x2, $y1, $x, $y2); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'delta': $arrpoints = array($x1, $y2, $x2, $y2, $x, $y1); ImageFilledPolygon($this->img, $arrpoints, 3, $color); break; case 'star': ImageLine($this->img, $x1, $y, $x2, $y, $color); ImageLine($this->img, $x, $y1, $x, $y2, $color); ImageLine($this->img, $x1, $y1, $x2, $y2, $color); ImageLine($this->img, $x1, $y2, $x2, $y1, $color); break; case 'hourglass': $arrpoints = array($x1, $y1, $x2, $y1, $x1, $y2, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'bowtie': $arrpoints = array($x1, $y1, $x1, $y2, $x2, $y1, $x2, $y2); ImageFilledPolygon($this->img, $arrpoints, 4, $color); break; case 'target': ImageFilledRectangle($this->img, $x1, $y1, $x, $y, $color); ImageFilledRectangle($this->img, $x, $y, $x2, $y2, $color); ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'box': ImageRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; case 'home': /* As in: "home plate" (baseball), also looks sort of like a house. */ $arrpoints = array($x1, $y2, $x2, $y2, $x2, $y, $x, $y1, $x1, $y); ImageFilledPolygon($this->img, $arrpoints, 5, $color); break; case 'up': ImagePolygon($this->img, array($x, $y1, $x2, $y2, $x1, $y2), 3, $color); break; case 'down': ImagePolygon($this->img, array($x, $y2, $x1, $y1, $x2, $y1), 3, $color); break; default: /* Also 'rect' */ ImageFilledRectangle($this->img, $x1, $y1, $x2, $y2, $color); break; } return TRUE; }
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); } ImagePolygon($temp_bg, $points, intval(sizeof($points) / 2), $text_colour3); } } else { if ($bg_type == 3) { // take random chunks of $bg_images and paste them onto the background $img_num = sizeof($bg_images); for ($i = 0; $i < $img_num; $i++) { // read each image and its size $temp_im[$i] = ImageCreateFromJPEG($bg_dir . $bg_images[$i]); $temp_width[$i] = imagesx($temp_im[$i]); $temp_height[$i] = imagesy($temp_im[$i]); } $blocksize = $rand_func(20, 60); for ($i = 0; $i < $width * 2; $i += $blocksize) { // could randomise blocksize here... hardly matters for ($j = 0; $j < $height * 2; $j += $blocksize) {
$points2[2 * $i + 2] = 100; $points2[2 * $i + 3] = $ycenter; ImageFilledPolygon($image, $points2, $the3 - $ths3 + 2, $line3); ImagePolygon($image, $points2, $the3 - $ths3 + 2, $black); // Calculate the slice for Admin $points2[0] = 100; $points2[1] = $ycenter; for ($i = 0; $i <= $the4 - $ths4; $i += 1) { $theta = ($i + $ths4) / 100; $points2[2 * $i + 2] = round(100 + 80 * sin($theta)); $points2[2 * $i + 3] = round($ycenter + 80 * cos($theta)); } $points2[2 * $i + 2] = 100; $points2[2 * $i + 3] = $ycenter; ImageFilledPolygon($image, $points2, $the4 - $ths4 + 2, $line4); ImagePolygon($image, $points2, $the4 - $ths4 + 2, $black); // Label the graph ImageString($image, 5, 110, 3, 'Effort by Category', $black); ImageString($image, 3, 60, 200, 'All Periods', $black); ImageString($image, 3, 230, 200, 'Latest Period', $black); // Outline the image ImageLine($image, 0, 0, 379, 0, $dark); ImageLine($image, 379, 0, 379, 219, $dark); ImageLine($image, 379, 219, 0, 219, $dark); ImageLine($image, 0, 219, 0, 0, $dark); // Expose the graph header('Content-type: image/png'); ImagePNG($image); // echo "</p>\n"; //echo "</table>\n"; //echo "<P>\n";
$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);
/** * Output the axis * @access private */ function _done() { parent::_done(); if (!$this->_font) { $this->_font = $GLOBALS['_Image_Graph_font']; } $value = $this->_getNextLabel(); $lastPosition = false; $this->_debug("Enumerating values from $value to ".$this->_getMaximum()); while ($value <= $this->_getMaximum()) { if ((((abs($value) > 0.0001) or ($this->_showLabelZero)) and (($value > $this->_getMinimum()) or ($this->_showLabelMinimum)) and (($value < $this->_getMaximum()) or ($this->_showLabelMaximum))) and ($value>= $this->_getMinimum()) and ($value<= $this->_getMaximum())) { $labelPosition = $this->_point($value); if (is_object($this->_dataPreProcessor)) { $labelText = $this->_dataPreProcessor->_process($value); } else { $labelText = $value; } $doOutput = false; if ($this->_type == IMAGE_GRAPH_AXIS_Y) { $text = new Image_Graph_Text($this->_right - 3, $labelPosition, $labelText, $this->_font); $text->setAlignment(IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_RIGHT); if (($text->_fillBottom() < $lastPosition) or ($lastPosition === false)) { $lastPosition = $text->_fillTop(); $doOutput = true; } } else { $text = new Image_Graph_Text($labelPosition, $this->_top + 3, $labelText, $this->_font); $text->setAlignment(IMAGE_GRAPH_ALIGN_CENTER_X | IMAGE_GRAPH_ALIGN_TOP); if (($text->_fillLeft() > $lastPosition) or ($lastPosition === false)) { $lastPosition = $text->_fillRight(); $doOutput = true; } } if ($doOutput) { $this->add($text); $text->_done(); } if ($this->_type == IMAGE_GRAPH_AXIS_Y) { ImageLine($this->_canvas(), $this->_right, $labelPosition, $this->_right + 6, $labelPosition, $this->_getLineStyle()); } else { ImageLine($this->_canvas(), $labelPosition, $this->_top, $labelPosition, $this->_top - 6, $this->_getLineStyle()); } } $nextValue = $this->_getNextLabel($value); /* if ($minorLabelInterval = $this->_minorLabelInterval()) { $minorValue = $value + $minorLabelInterval; while (($minorValue < $nextValue) and ($minorValue < $this->_getMaximum() - $minorLabelInterval)) { if ($minorValue >= $this->_getMinimum()) { $position = $this->_point($minorValue); if ($this->_type == IMAGE_GRAPH_AXIS_Y) { ImageLine($this->_canvas(), $this->_right, $position, $this->_right + 3, $position, $this->_getLineStyle()); } else { ImageLine($this->_canvas(), $position, $this->_top, $position, $this->_top - 3, $this->_getLineStyle()); } } $minorValue += $minorLabelInterval; } }*/ $value = $nextValue; } if ($this->_type == IMAGE_GRAPH_AXIS_Y) { ImageLine($this->_canvas(), $this->_right, $this->_top, $this->_right, $this->_bottom, $this->_getLineStyle()); if ($this->_showArrow) { $arrow[] = $this->_right - 5; $arrow[] = $this->_top + 8; $arrow[] = $this->_right; $arrow[] = $this->_top; $arrow[] = $this->_right + 5; $arrow[] = $this->_top + 8; ImageFilledPolygon($this->_canvas(), $arrow, count($arrow) / 2, $this->_getFillStyle()); ImagePolygon($this->_canvas(), $arrow, count($arrow) / 2, $this->_getLineStyle()); } } else { ImageLine($this->_canvas(), $this->_left, $this->_top, $this->_right, $this->_top, $this->_getLineStyle()); if ($this->_showArrow) { $arrow[] = $this->_right - 8; $arrow[] = $this->_top + 5; $arrow[] = $this->_right; $arrow[] = $this->_top; $arrow[] = $this->_right - 8; $arrow[] = $this->_top - 5; ImageFilledPolygon($this->_canvas(), $arrow, count($arrow) / 2, $this->_getFillStyle()); ImagePolygon($this->_canvas(), $arrow, count($arrow) / 2, $this->_getLineStyle()); } } }
<?php $points = array($x1, $y1, $x2, $y2, $x3, $y3); ImagePolygon($image, $points, count($points) / 2, $color);
break; } if ($n == 0 && count($maxcharsinline) == 1) { break; } else { $n++; } $maxstrlen += $maxcharsinline[$n] * 2; } while (true); // end preparations header("Content-type: image/png"); $decision = ImageCreate($width + 1, $height + 1); $white = ImageColorAllocate($decision, 255, 255, 255); $black = ImageColorAllocate($decision, 0, 0, 0); $points = array(0, floor($height / 2), floor($width / 2), 0, $width, floor($height / 2), floor($width / 2), $height); ImagePolygon($decision, $points, 4, $black); $yvalue = 0; if (strlen($textline[count($maxcharsperline)]) == '0' && count($maxcharsperline) % 2 == '0') { $yoffset = round($fontheight / 2); } else { $yoffset = 0; } log2file('[drawDcs] textline: ' . strlen($textline[count($maxcharsperline)])); for ($n = 0; $n <= $m; $n++) { log2file('[drawDcs] strlen of textline[$n]: ' . strlen($textline[$n])); if (strlen($textline[$n] == '0')) { $yvalue = round($fontheight / 2); log2file('[drawDcs] strlen=0'); } else { $xval = $leftx[$n] + strlen($textline[$n]) * $fontwidth / 3; log2file('[drawDcs] xval: $xval');
function draw_plage($im, $results, $flg, $sx, $sy, $xc, $yc, $xi, $yi) { reset($results); $lon = $results['LON']; $lat = $results['LAT']; $lon_b = xtrans($results['LON_B'] + 360 * $flg, $xc, $xi, $sx); $lat_b = ytrans($results['LAT_B'], $yc, $yi, $sy); $nb = count($lon); /*if ($flg == 0) $col=ImageColorAllocate($im, 105+50*$results['INTENSITY'][0], 0, 0); else $col=ImageColorAllocate($im, 105+50*$results['INTENSITY'][0], 0, 105+50*$results['INTENSITY'][0]);*/ if ($flg == 0) { $col = ImageColorAllocate($im, 255, 200 - 66 * $results['INTENSITY'], 200 - 66 * $results['INTENSITY']); } else { $col = ImageColorAllocate($im, 255, 200 - 66 * $results['INTENSITY'], 255); } $cBlack = ImageColorAllocate($im, 0, 0, 0); for ($i = 0; $i < $nb; $i++) { $points[] = xtrans($lon[$i] + 360 * $flg, $xc, $xi, $sx); $points[] = ytrans($lat[$i], $yc, $yi, $sy); } if (count($points) > 0) { ImageFilledPolygon($im, $points, count($points) / 2, $col); ImagePolygon($im, $points, count($points) / 2, $cBlack); } imagefilledellipse($im, $lon_b, $lat_b, 2, 2, $cBlack); //ImageFilledRectangle($im, $lon_b-1, $lat_b-1, $lon_b+1, $lat_b+1, $cBlack); //$fontwidth = ImageFontWidth($font); //$fontheight = ImageFontHeight($font); //ImageString($im, 2, $lon_b-($fontwidth/2), $lat_b-$fontheight, "x", $cBlack); unset($points); }
function draw_feat_pix($im, $tab_xpix, $tab_ypix, $c_x, $c_y, $intensity, $feat_id, $filled, $zoom) { global $global; $font_ttf = $global['FONT_PATH']; $sizey = imagesy($im); $nb = count($tab_xpix); $points = array(); if ($filled) { $col = ImageColorAllocate($im, 255, 255 - $intensity, 255 - $intensity); } else { $col = ImageColorAllocate($im, 255, 255, 255); } if ($filled) { $gc_col = ImageColorAllocate($im, 0, 0, 0); } else { $gc_col = ImageColorAllocate($im, 0, 0, 255); } for ($i = 0; $i < $nb; $i++) { $points[] = $tab_xpix[$i] * $zoom; $points[] = $sizey - $tab_ypix[$i] * $zoom; // en PHP, l'origine de l'image est coin gauche haut } if (count($points) > 0) { if ($filled) { ImageFilledPolygon($im, $points, $nb, $col); } ImagePolygon($im, $points, $nb, $col); } imagefilledellipse($im, $c_x * $zoom, $sizey - $c_y * $zoom, 2, 2, $gc_col); //ImageString ($im, 3, $c_x*$zoom-strlen($feat_id), $sizey-$c_y*$zoom+5, $feat_id, $gc_col); $textArray = explode(' ', $feat_id); $y = $sizey - $c_y * $zoom + 15; foreach ($textArray as $txt) { ImageTTFText($im, 8, 0, $c_x * $zoom - strlen($feat_id) + 10, $y, $gc_col, $font_ttf, $txt); $y += 15; } //ImageTTFText($im, 8, 0, $c_x*$zoom-strlen($feat_id)+10, $sizey-$c_y*$zoom+15, $gc_col, $font_ttf, $feat_id); }
<?php header("Content-type: image/png"); // 1 : on indique qu'on va envoyer une image PNG $image = imagecreate(400, 380); // 2 : on crée une nouvelle image de taille 400 x 350 // 3 : on s'amuse avec notre image (on va apprendre à le faire) $orange = imagecolorallocate($image, 255, 128, 0); $bleu = imagecolorallocate($image, 0, 0, 255); $bleuclair = imagecolorallocate($image, 156, 227, 254); $noir = imagecolorallocate($image, 0, 0, 0); $blanc = imagecolorallocate($image, 255, 255, 255); //ecrire un texte imagestring($image, 4, 35, 15, "Salut les Zéros !", $blanc); // dessiner un trait ImageLine($image, 30, 30, 120, 120, $noir); //Voici une illustration en figure suivante. ImageEllipse($image, 100, 100, 100, 50, $noir); // un rectangle ImageRectangle($image, 30, 30, 160, 120, $noir); //un triangle $points = array(10, 40, 120, 50, 160, 160); ImagePolygon($image, $points, 3, $noir); //imagecolortransparent($image, $orange); // On rend le fond orange transparent imagepng($image); // 4 : on a fini de faire joujou, on demande à afficher l'image
for ($i = 0; $i < $num_points; $i++) { //Compute the point $points[$i * 2] = $x_center + $data[$i] * $radius / 10 * cos(deg2rad($angles[$i])); $points[$i * 2 + 1] = $y_center - $data[$i] * $radius / 10 * sin(deg2rad($angles[$i])); } ImageFilledPolygon($im, $points, $num_points, $orange); ImagePolygon($im, $points, $num_points, $blue); //Plot the sub-areas $suba_nb = 4; for ($i = 0; $i < $suba_nb; $i++) { for ($j = 0; $j < $num_points; $j++) { //Compute the point $points[$j * 2] = $x_center + $radius / $suba_nb * ($i + 1) * cos(deg2rad($angles[$j])); $points[$j * 2 + 1] = $y_center - $radius / $suba_nb * ($i + 1) * sin(deg2rad($angles[$j])); } ImagePolygon($im, $points, $num_points, $grey); } //Plot the axis for ($i = 0; $i < $num_points; $i++) { //Axis $x = $x_center + $radius * cos(deg2rad($angles[$i])); $y = $y_center - $radius * sin(deg2rad($angles[$i])); ImageLine($im, $x_center, $y_center, $x, $y, $black); //Division $x1 = $x - $div_length / 2 * sin(deg2rad($angles[$i])); $x2 = $x + $div_length / 2 * sin(deg2rad($angles[$i])); $y1 = $y - $div_length / 2 * cos(deg2rad($angles[$i])); $y2 = $y + $div_length / 2 * cos(deg2rad($angles[$i])); ImageLine($im, $x1, $y1, $x2, $y2, $black); //Write the value & label $offset_center = -6;
/** * 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; }