Link to home
Start Free TrialLog in
Avatar of Cyber-Drugs
Cyber-DrugsFlag for United Kingdom of Great Britain and Northern Ireland

asked on

modifying a line function to support dotted lines

Hi guys,

In a previous question of mine RQuadline gave me a lovely Function which allows me to draw lines, specify the color and width.

I would like to modify the function so that when it is called, an extra parameter is sent to specify if it is to draw a dotted, or a solid line, but I want to keep the ability to specify the thickness.

Here's the code I have at the moment from RQuadling:

<?php
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1)
{
   /* this way it works well only for orthogonal lines
   imagesetthickness($image, $thick);
   return imageline($image, $x1, $y1, $x2, $y2, $color);
   */
   if ($thick == 1) {
       return imageline($image, $x1, $y1, $x2, $y2, $color);
   }
   $t = $thick / 2 - 0.5;
   if ($x1 == $x2 || $y1 == $y2) {
       return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
   }
   $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
   $a = $t / sqrt(1 + pow($k, 2));
   $points = array(
       round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
       round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
       round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
       round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
   );    
   imagefilledpolygon($image, $points, 4, $color);
   return imagepolygon($image, $points, 4, $color);
}


$image = imagecreate(100, 100);
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
imagelinethick($image, 0, 0, 99, 99, $white, 6);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>


Cheers guys!
Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

<?php
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1, $a_style = NULL)
{
   /* this way it works well only for orthogonal lines
   imagesetthickness($image, $thick);
   return imageline($image, $x1, $y1, $x2, $y2, $color);
   */
   
   if (!is_null($a_style))
         {
         imagesetstyle($image, $a_style);
         }
 
   if ($thick == 1) {
       return @imageline($image, $x1, $y1, $x2, $y2, (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
   }
   $t = $thick / 2 - 0.5;
   if ($x1 == $x2 || $y1 == $y2) {
       return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
   }
 
   $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
   $a = $t / sqrt(1 + pow($k, 2));
   $points = array(
       round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
       round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
       round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
       round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
   );    
   return imagefilledpolygon($image, $points, 4, (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
}


$image = imagecreate(100, 100);
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$a_style = array($white, $white, $white, $white, $white, $black, $black, $black, $black, $black);

imagelinethick($image, 0, 0, 99, 99, $white, 6, $a_style);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>

results in a slightly odd line along the bottom. As this code is all grabbed from the manual (with my mods), I'm not too sure what is not working correctly. Yet.
Fixed.

Instead of line being from 0,0 to 99,99, line is from 0,0 to 100,100;


<?php
function imagelinethick($image, $x1, $y1, $x2, $y2, $color, $thick = 1, $a_style = NULL)
{
   /* this way it works well only for orthogonal lines
   imagesetthickness($image, $thick);
   return imageline($image, $x1, $y1, $x2, $y2, $color);
   */
   
   if (!is_null($a_style))
         {
         imagesetstyle($image, $a_style);
         }
 
   if ($thick == 1) {
       return @imageline($image, $x1, $y1, $x2, $y2, (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
   }
   $t = $thick / 2 - 0.5;
   if ($x1 == $x2 || $y1 == $y2) {
       return imagefilledrectangle($image, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
   }
 
   $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
   $a = $t / sqrt(1 + pow($k, 2));
   $points = array(
       round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
       round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
       round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
       round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
   );    
   return imagefilledpolygon($image, $points, 4, (!is_null($a_style) ? IMG_COLOR_STYLED : $color));
}

$size = 100;
$image = imagecreate($size, $size);
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$a_style = array($white, $white, $white, $white, $white, $black, $black, $black, $black, $black);

imagelinethick($image, 0, 0, $size, $size, $white, 6, $a_style);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>
But, having said that, the line dashes are NOT rotated with the line.
So, draw the line straight and then rotate it should work.

But playing with the array and the width produces some interesting results!!!!

$a_style = array($white, $white, $white, $white, $white, $black, $black, $black, $black, $black);
imagelinethick($image, 0, 0, $size, $size, $white, 20, $a_style);

Very odd!


The other way (I think) is to construct a brush which is the right dash size you want and use that as the image, using IMG_COLOR_STYLEDBRUSHED rather than IMG_COLOR_STYLED
Avatar of Cyber-Drugs

ASKER

Hi RQuadling,

Thanks for the fast reply, but I've got a small problem with that code you've just posted...


When I use this code, I get a rectangle with a dotted outline, rather than a dotted line 4 pixels thick...

$image = imagecreate(48, 48);
$gray = imagecolorallocate($image, 192, 192, 192);
$black = imagecolorallocate($image, 0, 0, 0);
if ($_GET['color'] != ''){
      $color = HexToRGB($_GET['color']);
} else {
      $color[0] = 255;
      $color[1] = 255;
      $color[2] = 255;
}
$line = imagecolorallocate($image, $color[0], $color[1], $color[2]);
if ($_GET['style'] == 'dotted'){
      $a_style = array(
            $line,
            $line,
            $line
      );
} elseif ($_GET['style'] == 'solid'){
      $a_style = NULL;
}
imagelinethick($image, 5, 43, 43, 5, $line, 4, $a_style);
imageline($image, 0, 0, 0, 47, $black);
imageline($image, 0, 0, 47, 0, $black);
imageline($image, 47, 0, 47, 47, $black);
imageline($image, 0, 47, 47, 47, $black);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);


Is it a fault on my end?

Cheers!
ASKER CERTIFIED SOLUTION
Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You can also use ...
imagerectangle($image, 0, 0, 47, 47, $black);

instead of ...

imageline($image, 0, 0, 0, 47, $black);
imageline($image, 0, 0, 47, 0, $black);
imageline($image, 47, 0, 47, 47, $black);
imageline($image, 0, 47, 47, 47, $black);

Ah, that works.

Cheers! :)