Solved

# modifying a line function to support dotted lines

Posted on 2006-07-14
513 Views
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);
imagepng(\$image);
imagedestroy(\$image);
?>

Cheers guys!
0
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
• 6
• 2

LVL 40

Expert Comment

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

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);
imagepng(\$image);
imagedestroy(\$image);
?>
0

LVL 40

Expert Comment

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

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

ID: 17107859

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);
imagepng(\$image);
imagedestroy(\$image);

Is it a fault on my end?

Cheers!
0

LVL 40

Accepted Solution

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

ID: 17107964
You can also use ...
imagerectangle(\$image, 0, 0, 47, 47, \$black);

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

ID: 17107983
Ah, that works.

Cheers! :)
0

## Featured Post

Question has a verified solution.

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

### Suggested Solutions

This article discusses four methods for overlaying images in a container on a web page
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
###### Suggested Courses
Course of the Month4 days, 12 hours left to enroll