Solved

modifying a line function to support dotted lines

Posted on 2006-07-14
8
504 Views
Last Modified: 2013-12-12
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!
0
Comment
Question by:Cyber-Drugs
  • 6
  • 2
8 Comments
 
LVL 40

Expert Comment

by:RQuadling
ID: 17107734
<?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.
0
 
LVL 40

Expert Comment

by:RQuadling
ID: 17107740
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);
?>
0
 
LVL 40

Expert Comment

by:RQuadling
ID: 17107772
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!


0
 
LVL 40

Expert Comment

by:RQuadling
ID: 17107791
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
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 17107859
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!
0
 
LVL 40

Accepted Solution

by:
RQuadling earned 500 total points
ID: 17107946
<?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, 9, $a_style);
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
*/

$image = imagecreate(48, 48);
$gray = imagecolorallocate($image, 192, 192, 192);
$black = imagecolorallocate($image, 0, 0, 0);
$color = array(255,255,255);
if (isset($_GET['color']) && ($_GET['color'] != ''))
      {
      $color = HexToRGB($_GET['color']);
      }
$line = imagecolorallocate($image, $color[0], $color[1], $color[2]);
$a_style = NULL;
if (isset($_GET['style']) && ($_GET['style'] == 'dotted'))
      {
      $a_style = array
            (
            $line,
            $gray,
            $line,
            $gray,
            $line
            );
      }

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);
?>

With a url which has ?style=dotted, I get a dotted line.

The style has to include on/off sort of pattern.

Try ...

if (isset($_GET['style']) && ($_GET['style'] == 'dotted'))
      {
      $a_style = array
            (
            $line,
            $gray,
            );
      }

also.
0
 
LVL 40

Expert Comment

by:RQuadling
ID: 17107964
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);

0
 
LVL 4

Author Comment

by:Cyber-Drugs
ID: 17107983
Ah, that works.

Cheers! :)
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Build an array called $myWeek which will hold the array elements Today, Yesterday and then builds up the rest of the week by the name of the day going back 1 week.   (CODE) (CODE) Then you just need to pass your date to the function. If i…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now