Solved

modifying a line function to support dotted lines

Posted on 2006-07-14
8
503 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
spacing 5 31
echo button 13 47
Use PHP to save or display image returned by JSON call. 20 51
lastpass auto fill login form 5 25
Introduction Many web sites contain image galleries; a common design for these galleries includes a page with a collection of thumbnail images.  You can click on each of the thumbnail images to see the larger version of the image.  This is easily i…
Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

762 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

18 Experts available now in Live!

Get 1:1 Help Now