1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
|
#!/usr/bin/perl
#
# Demonstration of some of the fancier Image Composition Methods
# including the 'rotate' parameter specific to PerlMagick Composite()
#
# NOTE: versions of IM older than IM v6.5.3-4 will need to rename the
# parameter "args=>" to the mis-named "blend=>" parameter.
#
# Also not that "composite -watermark" is actually known as the compose
# method "Modulate".
#
# Essentually each image is equivelent to
# convert logo: -crop 80x80+140+60 +repage \
# -size 60x60 gradient:black-white \
# -alpha set miff:- |\
# composite - -geometry +10+10 -virtual-pixel gray \
# -dissolve 70x30 show:
# for various composition methods.
#
use strict;
use Image::Magick;
# Background or Destination image
my $dest=Image::Magick->new();
$dest->Read('logo:');
$dest->Crop('100x100+400+100'); # wizards hat
$dest->Set(page=>'0x0+0+0');
$dest->Set(alpha=>'Set');
# Source, Composite or Overlay image
my $src=Image::Magick->new();
$src->Set(size=>'80x80');
$src->Read('gradient:black-white');
$src->Set(alpha=>'Set');
my $offset="+10+10";
# Circle Mask Image (same size as Destination)
my $circle=Image::Magick->new();
$circle->Set(size=>'100x100');
$circle->Read('xc:black');
$circle->Draw(fill=>'white',primitive=>'circle',points=>'49.5,49.5 10,49.5');
my $texture=Image::Magick->new();
$texture->Read('pattern:checkerboard');
# List of images generated
my $results=Image::Magick->new();
# Working copy of Destination Image
my $clone;
# ----------------------------------------
# Normal Composition Methods
$clone=$dest->Clone();
$clone->Label('Over\n(normal compose)');
$clone->Composite(
image=>$src,
compose=>'over',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Multiply\n(add black)');
$clone->Composite(
image=>$src,
compose=>'multiply',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Screen\n(add white)');
$clone->Composite(
image=>$src,
compose=>'screen',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('HardLight\n(light effects)');
$clone->Composite(
image=>$src,
compose=>'hardlight',
geometry=>$offset,
);
push(@$results, $clone);
# ---------------
# Masked and Blending Demonstartion
$clone=$dest->Clone();
$clone->Label('Circle Masked\n(three image)');
$clone->Composite(
image=>$src,
mask=>$circle,
compose=>'over',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Blend 50x50\n(50% plus 50%)');
$clone->Composite(
image=>$src,
compose=>'blend',
args=>'50x50',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Dissolve 50x50\n(50% over 50%)');
$clone->Composite(
image=>$src,
compose=>'dissolve',
args=>'50x50',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Dissolve 50\n(50% over 100%)');
$clone->Composite(
image=>$src,
compose=>'dissolve',
args=>'50',
geometry=>$offset,
);
push(@$results, $clone);
# ---------------
# Displacement Demonstartion
$clone=$dest->Clone();
$clone->Label('Displace 50x0\n(displace horiz)');
$clone->Set('virtual-pixel'=>'gray');
$clone->Composite(
image=>$src,
compose=>'displace',
args=>'50x0',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Displace 0x50\n(compress vert)');
$clone->Set('virtual-pixel'=>'gray');
$clone->Composite(
image=>$src,
compose=>'displace',
args=>'0x50',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Displace 50x50\n(diagonal)');
$clone->Set('virtual-pixel'=>'gray');
$clone->Composite(
image=>$src,
compose=>'displace',
args=>'50x50',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Displace 0,-80\n(displace flip)');
$clone->Set('virtual-pixel'=>'gray');
$clone->Composite(
image=>$src,
compose=>'displace',
args=>'0,-80',
geometry=>$offset,
);
push(@$results, $clone);
# ---------------
# Demonstrate rotation
# note that offset is automatically adjusted to keep rotated image
# centered relative to its '0' rotation position
$clone=$dest->Clone();
$clone->Label('Rotate 0\n');
$clone->Composite(
image=>$src,
compose=>'over',
rotate=>0,
background=>'none',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Rotate 10\n');
$clone->Composite(
image=>$src,
compose=>'over',
rotate=>10,
background=>'none',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Rotate 45\n');
$clone->Composite(
image=>$src,
compose=>'over',
rotate=>45,
background=>'none',
geometry=>$offset,
);
push(@$results, $clone);
$clone=$dest->Clone();
$clone->Label('Rotate 90\n');
$clone->Composite(
image=>$src,
compose=>'over',
rotate=>90,
background=>'none',
geometry=>$offset,
);
push(@$results, $clone);
# ----------------------------------------
# Output the changed pixels
# to every image underlay a checkboard pattern
# so as to show if any transparency is present
for my $image ( @$results ) {
$image->Composite(
image=>$texture,
tile=>'True',
compose=>'DstOver',
);
}
my $montage=$results->Montage(
geometry=>'+10+10',
tile=>'4x',
frame=>'6x6+2+2',
shadow=>'True',
);
$montage->Write('show:');
$montage->Write('compose_specials.jpg');
|