1=pod 2 3=head1 NAME 4 5examples/blend.pl - Prima alpha blending 6 7=head1 FEATURES 8 9Demonstrates use of Prima image alpha blending with C<rop::blend($ALPHA)>. 10 11=cut 12 13 14use strict; 15use warnings; 16use Prima qw(Application Label Sliders ImageViewer); 17 18my ($rop_name, $rop_val); 19my $w = Prima::MainWindow->new( 20 size => [ 600, 500 ], 21 designScale => [7, 16], 22 text => 'Blending example', 23 menuItems => [ 24 [ '~Binary' => [ map { [$_, $_, \&bin, {group => 1}] } qw( 25 CopyPut XorPut AndPut OrPut NotPut Invert Blackness 26 NotDestAnd NotDestOr Whiteness NotSrcAnd NotSrcOr NotXor 27 NotAnd NotOr NoOper 28 )]], 29 [ 'Porter-~Duff' => [ map { [$_, $_, \&pd, {group => 1}] } qw( 30 SrcOver Xor DstOver SrcCopy DstCopy Clear 31 SrcIn DstIn SrcOut DstOut SrcAtop DstAtop 32 )]], 33 [ '~Photoshop' => [ map { [$_, $_, \&pd, {group => 1}] } qw( 34 Add Multiply Screen Overlay Darken 35 Lighten ColorDodge ColorBurn HardLight 36 SoftLight Difference Exclusion 37 )]], 38 ] 39); 40 41my $a = Prima::Image->new( 42 size => [200,200], 43 type => im::RGB, 44); 45$a->begin_paint; 46$a->new_gradient( palette => [cl::LightGreen, cl::Blue ])->bar(0, 0, $a->size); 47$a->end_paint; 48my $ia = Prima::Icon->new( 49 size => [200,200], 50 type => im::RGB, 51 maskType => im::bpp8, 52 autoMasking => am::MaskColor, 53 maskColor => cl::Black, 54); 55$ia->put_image(0,0,$a); 56$ia->color(cl::Black); 57$ia->bar(0,0,30,200); 58$ia->bar(170,0,200,200); 59 60my $b = $a->dup; 61$b->begin_paint; 62$b->bar(0,0,$b->size); 63$b->new_gradient( palette => [cl::LightRed, cl::Yellow ])-> ellipse($b->width/2,$b->height/2, $b->size); 64$b->end_paint; 65 66my $ib = Prima::Icon->new( 67 size => [200,200], 68 type => im::RGB, 69 maskType => im::bpp8, 70 autoMasking => am::MaskColor, 71 maskColor => cl::Black, 72); 73$ib->put_image( 0,0,$b); 74 75my $base = $a->dup; 76$base->set( backColor => cl::White, color => cl::Black, fillPattern => [(0xF0)x4, (0xF)x4], rop2 => rop::CopyPut); 77$base->bar(0,0,$base->size); 78 79my $canvas = $a->dup; 80my $precanvas = Prima::Icon->new( 81 size => [200,200], 82 type => im::RGB, 83 maskType => im::bpp8, 84 autoMasking => am::None, 85); 86$ia->autoMasking(am::None); 87 88my $mask = Prima::Image->new( 89 size => [200,200], 90 type => im::Byte, 91); 92 93sub repaint 94{ 95 my $sa = $w->SliderA; 96 my $sb = $w->SliderB; 97 if ( $sa->enabled ) { 98 $precanvas->put_image(0,0,$ia, rop::alpha( rop::SrcCopy | rop::Premultiply, $sa->value)); 99 $precanvas->put_image(0,0,$ib, rop::alpha( $rop_val | rop::Premultiply, $sb->value)); 100 $canvas->put_image(0,0,$base); 101 $canvas->put_image(0,0,$precanvas); 102 } else { 103 $canvas->put_image(0,0,$a); 104 $canvas->put_image(0,0,$b,$rop_val); 105 } 106 107 my $fader = $w->Fader; 108 $canvas->put_image(2, 2, $fader->{banner}, rop::alpha( rop::SrcOver | rop::Premultiply, $fader->{alpha} )) 109 if $fader->{banner}; 110 $w-> ImageViewer1->repaint; 111} 112 113sub select_rop 114{ 115 my ($newrop, $with_slider) = @_; 116 $rop_name = $newrop; 117 $rop_val = &{${rop::}{$rop_name}}(); 118 $w->SliderA->enabled( $with_slider ); 119 $w->SliderA->readOnly( !$with_slider ); 120 $w->SliderB->enabled( $with_slider ); 121 $w->SliderB->readOnly( !$with_slider ); 122 $w->Fader->{text} = $rop_name; 123 delete $w->Fader->{left}; 124 $w->Fader->{steps} = 30; 125 $w->Fader->start; 126 repaint(); 127} 128 129sub set_slider 130{ 131 $w->Fader->{text} = shift->value; 132 $w->Fader->{steps} = 15; 133 delete $w->Fader->{left}; 134 $w->Fader->start; 135 repaint(); 136} 137sub bin { select_rop($_[1], 0) } 138sub pd { select_rop($_[1], 1) } 139 140 141$w-> insert( ImageViewer => 142 pack => {side => 'top', fill => 'both', pad => 10, expand => 1}, 143 image => $canvas, 144 stretch => 1, 145); 146 147$w->insert( Label => 148 text => '~Green transparency', 149 focusLink => 'SliderA', 150 pack => {side => 'top', fill => 'x', padx => 15}, 151); 152 153$w->insert( Slider => 154 min => 0, 155 max => 255, 156 value => 200, 157 scheme => ss::Axis, 158 increment => 16, 159 name => 'SliderA', 160 pack => {side => 'top', fill => 'x'}, 161 onChange => \&set_slider, 162); 163 164$w->insert( Label => 165 text => '~Red transparency', 166 focusLink => 'SliderB', 167 pack => {side => 'top', fill => 'x', padx => 15}, 168); 169 170$w->insert( Slider => 171 min => 0, 172 max => 255, 173 scheme => ss::Axis, 174 increment => 16, 175 value => 200, 176 name => 'SliderB', 177 pack => {side => 'top', fill => 'x'}, 178 onChange => \&set_slider, 179); 180 181$w-> insert( Timer => 182 timeout => 50, 183 name => 'Fader', 184 onTick => sub { 185 my $self = shift; 186 if ( !defined $self->{left}) { 187 $self->{left} = $self->{steps}; 188 $canvas-> begin_paint_info; 189 $canvas->font->set( size => 18, style => fs::Bold ); 190 my $f = $canvas->font; 191 my $b = Prima::Icon->new( 192 type => im::RGB, 193 size => [ $canvas->get_text_width( $self->{text}, 1 ) + 4, $f-> height + 4 ], 194 color => cl::Yellow, 195 backColor => cl::Black, 196 lineWidth => 5, 197 maskType => 8, 198 autoMasking => 0, 199 font => { vector => 1 }, 200 ); 201 $canvas-> end_paint_info; 202 $b->begin_paint; 203 $b->clear; 204 $b->font->set( size => 18, style => fs::Bold ); 205 $b->color(0x010101); # black but not zero 206 my $path = $b->new_path; 207 $path->translate(2,2); 208 $path->text( $self->{text}); 209 $path->stroke; 210 $b->color(cl::Yellow); 211 $b->text_out($self->{text}, 2, 2); 212 $b->end_paint; 213 214 my $bb = $b->clone( type => im::Byte, rop2 => rop::CopyPut ); 215 $bb->map(0x000000); # black and zero 216 $b->mask( $bb->data ); 217 218 $self->{banner} = $b; 219 $self->{alpha} = 255; 220 } elsif ( --$self->{left} <= 0 ) { 221 delete $self->{banner}; 222 delete $self->{left}; 223 $self->stop; 224 } else { 225 $self->{alpha} -= 256 / $self->{steps}; 226 } 227 repaint; 228 }, 229); 230$w->Fader->{steps} = 30; 231 232select_rop('SrcOver', 1); 233 234run Prima; 235