Solved

modifying a line function to support dotted lines

Posted on 2006-07-14
8
519 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 2
8 Comments
 
LVL 40

Expert Comment

by:Richard Quadling
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:Richard Quadling
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:Richard Quadling
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
Don't Cry: How Liquid Web is Ensuring Security

WannaCry is just the start. Read how Liquid Web is protecting itself and its customers against new threats.

 
LVL 40

Expert Comment

by:Richard Quadling
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
 
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:
Richard Quadling 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:Richard Quadling
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

WordPress Tutorial 1: Installation & Setup

WordPress is a very popular option for running your web site and can be used to get your content online quickly for the world to see. This guide will walk you through installing the WordPress server software and the initial setup process.

Question has a verified solution.

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

I imagine that there are some, like me, who require a way of getting currency exchange rates for implementation in web project from time to time, so I thought I would share a solution that I have developed for this purpose. It turns out that Yaho…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
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…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

635 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