1#!/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=>'80x80'); 41$circle->Read('xc:black'); 42$circle->Draw(fill=>'white',primitive=>'circle',points=>'39.5,39.5 10,39.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 253