7 my $shadow_size = "10%";
9 my $shadow_color = "#404040";
13 "size|s=s" => \$shadow_size,
14 "o|offset=s" => \$offset,
15 "s|shadow=s" => \$shadow_color,
21 Usage: $0 [options] infile outfile
22 Options can be any or all of:
23 -bg color - fill the background with a color instead of using
24 transparency, this can be a translucent color.
25 -size size - size of the shadow in pixels, or percent of min dimension
26 -offset <xsize>x<ysize> - offset of the original image within the shadow
27 -shadow color - color of the shadow
30 my $src = Imager->new(file => $infile)
31 or die "Cannot read image file '$infile': ", Imager->errstr, "\n";
33 # simplify things by always working in RGB rather than grey
34 $src = $src->convert(preset => "rgb");
36 if ($shadow_size =~ /^([0-9]+)%$/) {
37 my $dim = $src->getwidth < $src->getheight ? $src->getwidth : $src->getheight;
39 $shadow_size = int($1 * $dim / 100 + 0.5);
42 my ($x_offset, $y_offset) = $offset =~ /^([+-]?[0-9]+)x([+-]?[0-9]+)$/
43 or die "$0: invalid offset\n";
45 my $shc = Imager::Color->new($shadow_color)
46 or die "$0: invalid shadow color: ", Imager->errstr, "\n";
48 my ($red, $green, $blue) = $shc->rgba;
50 # First create a new image, either with an alpha channel (if you want
51 # transparency behind the shadow) or without, if you want a background
56 xsize => $shadow_size * 2 + $src->getwidth,
57 ysize => $shadow_size * 2 + $src->getheight,
62 # fill it with your background color, if you want one
63 my $bgc = Imager::Color->new($bg)
64 or die "$0: invalid color '$bg'\n";
65 $out->box(filled => 1, color => $bgc);
68 # Make a work image to render the shadow on:
69 my $shadow_work = Imager->new
71 xsize => $out->getwidth,
72 ysize => $out->getheight,
76 if ($src->getchannels == 4) {
77 # Extract the alpha channel from the source image, if the image has no
78 # alpha, then a solid box then it's simpler, first the alpha version:
79 my $alpha = $src->convert(preset => "alpha");
81 # and draw that on the work shadow:
90 # otherwise just draw a box for the non-alpha source:
98 xmax => $shadow_size + $src->getwidth() - 1,
99 ymax => $shadow_size + $src->getheight() - 1,
103 # Blur the work shadow:
105 $shadow_work->filter(type => "gaussian", stddev => $shadow_size);
107 # Convert it to an RGB image with alpha:
109 $shadow_work = $shadow_work->convert
111 matrix => [ [ 0, $red / 255 ],
115 ) or die $shadow_work->errstr;
117 # Draw that on the output image:
119 $out->rubthrough(src => $shadow_work);
121 # Draw our original image on the output image, perhaps with an offset:
125 tx => $shadow_size + $x_offset,
126 ty => $shadow_size + $y_offset,
129 $out->write(file => $outfile)
130 or die "Cannot write to '$outfile': ", $out->errstr, "\n";