Home | History | Annotate | Download | only in demo
      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 #
     20 use strict;
     21 use Image::Magick;
     22 
     23 # Background or Destination image
     24 my $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
     31 my $src=Image::Magick->new();
     32 $src->Set(size=>'80x80');
     33 $src->Read('gradient:black-white');
     34 $src->Set(alpha=>'Set');
     35 
     36 my $offset="+10+10";
     37 
     38 # Circle Mask Image (same size as Destination)
     39 my $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 
     44 my $texture=Image::Magick->new();
     45 $texture->Read('pattern:checkerboard');
     46 
     47 # List of images generated
     48 my $results=Image::Magick->new();
     49 
     50 # Working copy of Destination Image
     51 my $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 );
     63 push(@$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 );
     72 push(@$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 );
     81 push(@$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 );
     90 push(@$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 );
    103 push(@$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 );
    113 push(@$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 );
    123 push(@$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 );
    133 push(@$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 );
    147 push(@$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 );
    158 push(@$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 );
    169 push(@$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 );
    180 push(@$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 );
    196 push(@$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 );
    207 push(@$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 );
    218 push(@$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 );
    229 push(@$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
    236 for my $image ( @$results ) {
    237   $image->Composite(
    238     image=>$texture,
    239     tile=>'True',
    240     compose=>'DstOver',
    241   );
    242 }
    243 
    244 my $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