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