Using a Style to Draw a Dotted Line - Page 15
October 22, 2001
The GD library includes the ability to create drawing styles,
which is created by defining, in order, a list of colors that
makes up the style. Styles are set using the
setStyle() function:
$image->setStyle($black,$black,$white,$white);
The style can then be applied to various drawing routines
including rectangle() by passing
gdStyled as the color. Below is another border
application that uses a styled border.
1 use GD;
2 my $image = GD::Image->newFromJpeg("66044.jpg");
3 my $black = $image->colorResolve(0,0,0);
4 my $white = $image->colorResolve(255,255,255);
5 my ($width,$height) = $image->getBounds();
6 $image->setStyle($black,$black,$white,$white);
7 $image->rectangle(0,0,($width-1),($height-1),gdStyled);
8 open(FILE, ">border3.jpg") || die "Cannot open border3.jpg: $!\n";
9 print FILE $image->jpeg;
In lines 3 and 4, we allocate white and black into the color map
of the image we have loaded on line 2. If the color map is full
(256 colors), then it will return the index to the closest color
that already exists in the map. On line 6, we create a new
drawing style that consists of two black pixels, followed by two
while pixels. This is used to create a dotted line effect when
passed to the rectangle() function as the color on
line 7.
Setting a transparent color
It is a common practice to create images that have a transparent
color. For example, the image on the left uses a (mostly) black
background. Setting the background color of an image as
transparent creates a nice effect for graphical objects on an
HTML page. PNG is the only format that GD supports that also
supports transparent colors. The example below loads a JPEG
image, sets black as the transparent color, and saves the image
in the PNG format.
Note: If your browser does not support transparent PNG
settings, you will see a black background rather than a
transparent background
1 use GD;
2 my $image = GD::Image->newFromJpeg("169004-1.jpg");
3 my $black = $image->colorResolve(0,0,0);
4 $image->transparent($black);
5 $image->interlaced('true');
6 open(FILE, ">background1.png") || die "Cannot
open background1.jpg: $!\n";
7 print FILE $image->png;
[The red lines above are one line. They have been split for
formatting purposes.]
Line 3 allocates black or the closest color to black if the color
map is full. Line 4 sets black as the transparent color in the
image. We've also made the image interlaced on line 5. The
interlaced() is set to false by default.
If your browser does support transparent colors in PNG images,
you'll notice that there are a bunch of black spots that show up
in the image. These actually aren't black spots in the purest
sense of the RGB spectrum where black is 0,0,0 (Red, Green,
Blue). They're close to black but not quite. To get rid of these
black spots, you could edit the image manually or do it with a
script. To do it with Perl, we must scan the image for all pixels
that are very close to black and turn them into black pixels.
To scan the image for colors close to black, we need to decide on
an RGB range to search for. Any pixels that fall into the range will be
changed to the transparent color. In the example below, we get the
red, green, and blue values for each pixel in the image on line 11.
The getPixel() function returns the index of the color as it exists
in the color map. To get the red green and blue values for the color,
we call the rgb() function, passing the color that was returned
from the getPixel() function. The return value for rgb()
is an array that contains the numerical value (0-255) for red, green, and
blue (in that order). The higher the value, the brighter the color.
A value of zero for one of the three colors indicates that none of that
color is used. On line 13, we're looking for a color whose
RGB values are all less than 30. If there is a match, we set the pixel
to black so that it now becomes a transparent pixel.
1 use GD;
2 my $image = GD::Image->newFromJpeg("169004-1.jpg");
3 my $black = $image->colorResolve(0,0,0);
4 $image->transparent($black);
5 $image->interlaced('true');
6 my ($width,$height) = $image->getBounds();
7 my $count = 0;
8
9 for (my $x = 0; $x < $width; $x++) {
10 for (my $y = 0; $y < $height; $y++) {
11 my $color = $image->getPixel($x,$y);
12 my ($r,$g,$b) = $image->rgb($color);
13 if ($r < 30 && $g < 30 && $b < 30) {
14 $image->setPixel($x,$y,$black);
15 $count++;
16 }
17 }
18 }
19 print "$count\n";
20 open(FILE, ">background2.png") || die "Cannot
open background2.jpg: $!\n";
21 print FILE $image->png;
[The red lines above are one line. They have been split for
formatting purposes.]
While this image comes out fairly well, the script above may not
work for any image that contains a background. For example, if
the background color of an image is used in other parts of the
image other than the background, part of the image will be
transparent that should be solid. In these cases, you may have to
change the background to a color that does not occur anywhere
else in the image using an image editor like Adobe Photoshop.
This actually happens to a number of pixels in the image above
between the green stem and red skin of the pepper image above.
Automating Image Manipulation with GD - Page 14
Weaving Magic With Regular Expressions
Adding Text to Images - Page 16
|