How to draw thin lines with Image::Magick?

J

Josef Moellers

Hi,

I'd like to draw lines only one pixel thin using Image::Magick.
The following draws lines two pixels thick:

#! /usr/bin/perl

use warnings;
use strict;
use Image::Magick;

my $img = Image::Magick->new(size => '22x22');
$img->ReadImage('xc:white');
$img->Draw(primitive => 'line',
linewidth => 1,
method => 'point',
points => '0,10 20,10',
fill => 'black',
antialias => 'false',
);
$img->Transparent(color => 'white');
$img->Write('thick.png');


What options are required to draw lines one pixel wide?
Besides "linewidth" I also tried "strikewidth" to no avail.

Josef
 
S

Steve M.

Hi,

I'd like to draw lines only one pixel thin using Image::Magick. The
following draws lines two pixels thick:

#! /usr/bin/perl

use warnings;
use strict;
use Image::Magick;

my $img = Image::Magick->new(size => '22x22');
$img->ReadImage('xc:white');
$img->Draw(primitive => 'line',
linewidth => 1, <- ??????
method => 'point',
points => '0,10 20,10',
fill => 'black',
antialias => 'false',
);
$img->Transparent(color => 'white');
$img->Write('thick.png');


What options are required to draw lines one pixel wide? Besides
"linewidth" I also tried "strikewidth" to no avail.

Josef

Well...

$img -> Draw (
stroke => 'black',
primitive => 'line',
strokewidth => '1',
points => '1,10 20,10',
antialias => 'false',
);

should work.

I'm not sure where linewidth came from... strikewidth appears to be a
typo...

hth,

\s
 
J

Josef Moellers

Am 1.2.2011 schrub Steve M.:
Well...

$img -> Draw (
stroke => 'black',
primitive => 'line',
strokewidth => '1',
points => '1,10 20,10',
antialias => 'false',
);

should work.


Thanks but ... the line is still 2 pixels wide.
I'm not sure where linewidth came from... strikewidth appears to be a
typo...

I found the linewidth in some documentation, so I just gave it a try.
The str*i*kewith was indeed a typo: strokewidth => 1 does not work either.

Thanks anyway,

Josef

NB My perl is 5.10.1, my perlmagick is "ImageMagick 6.5.7-8 2010-12-02
Q16 http://www.imagemagick.org"
 
J

Josef Moellers

Am 1.2.2011 schrub Sherm Pendley:
Fair warning: I'm not familiar with IM. This is just an idea based on
my experience with other drawing APIs, so I apologize in advance if it
doesn't apply!

Is IM's drawing based on pixel coordinates, or on image coordinates?
For the former, X/Y coordinates denote the center points of pixels, so
a one-pixel line is exactly one pixel thick.

But, in image coordinates, X/Y denote the top left of a pixel, so that
integer coordinates represent the lines between pixels. With antialias-
ing, a one-pixel wide line would be rendered by coloring two adjacent
pixels at half value. To draw a true one-pixel line in such systems,
one must add 0.5 to both X and Y coordinates.


Now you did it! ;-)
Now the lines are 3 pixels wide!

It's certainly an idea worth investigating.

Thanks,

Josef
 
P

Peter J. Holzer

Am 1.2.2011 schrub Steve M.:
I'd like to draw lines only one pixel thin using Image::Magick. The
following draws lines two pixels thick: [...]
$img->Draw(primitive => 'line',
linewidth => 1, <- ??????
method => 'point',
points => '0,10 20,10',
fill => 'black',
antialias => 'false',
); [...]
What options are required to draw lines one pixel wide?
[...]
$img -> Draw (
stroke => 'black',
primitive => 'line',
strokewidth => '1',
points => '1,10 20,10',
antialias => 'false',
);

should work.


Thanks but ... the line is still 2 pixels wide.

Both variants work for me with Image::Magick 6.6.0 (Debian package
perlmagick 8:6.6.0.4-3).

hp
 
S

Steve M.

Am 1.2.2011 schrub Steve M.:




Thanks but ... the line is still 2 pixels wide.



Josef

NB My perl is 5.10.1, my perlmagick is "ImageMagick 6.5.7-8 2010-12-02
Q16 http://www.imagemagick.org"


Hmmm...... That code worked with my Perl (5.10.1) and ImageMagick....

Well, if you didn't care about fiddling with anti-alias nonsense, I
suppose you could:

for( 1..20 ){
$img->Set("pixel[$_,10]"=>'black');
}


Not efficient perhaps.

hth,
 
J

Josef Moellers

Am 2.2.2011 schrub Steve M.:
Am 1.2.2011 schrub Steve M.:




Thanks but ... the line is still 2 pixels wide.



Josef

NB My perl is 5.10.1, my perlmagick is "ImageMagick 6.5.7-8 2010-12-02
Q16 http://www.imagemagick.org"


Hmmm...... That code worked with my Perl (5.10.1) and ImageMagick....

Well, if you didn't care about fiddling with anti-alias nonsense, I
suppose you could:

for( 1..20 ){
$img->Set("pixel[$_,10]"=>'black');
}


Not efficient perhaps.

It wouldn't have been a problem, I stumbled across this when I tried to
draw a small 22x22 "dia" shape.
But it helped me find my problem. It's somewhere between the keyboard
and the chair: I was fooled by gimp!

When I tried to draw this pixel-by-pixel line, I found that when I
looked at it with gimp, gimp would show two different coordinates when I
moved the cursor from one side of the line to the other, which I
definitely thought could not be the case with "Set(pixel ...)"!
So I tried to select one pixel and ... indeed the line is only one pixel
wide! A 22x22 image with 22 vertical lines shows this to be correct.
Even with $img->Draw(...) the line is only one pixel wide!

Thanks for all the help and suggestions.

Josef
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top