]> git.imager.perl.org - imager.git/blame - Imager.pm
based on discussion with lathos on IRC
[imager.git] / Imager.pm
CommitLineData
02d1d628
AMH
1package Imager;
2
02d1d628
AMH
3use strict;
4use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR $fontstate %OPCODES $I2P $FORMATGUESS);
5use IO::File;
6
7use Imager::Color;
8use Imager::Font;
9
10@EXPORT_OK = qw(
11 init
12 init_log
13 DSO_open
14 DSO_close
15 DSO_funclist
16 DSO_call
dd55acc8 17
02d1d628
AMH
18 load_plugin
19 unload_plugin
dd55acc8 20
02d1d628
AMH
21 i_list_formats
22 i_has_format
dd55acc8 23
02d1d628
AMH
24 i_color_new
25 i_color_set
26 i_color_info
dd55acc8 27
02d1d628
AMH
28 i_img_empty
29 i_img_empty_ch
30 i_img_exorcise
31 i_img_destroy
32
33 i_img_info
34
35 i_img_setmask
36 i_img_getmask
37
38 i_draw
39 i_line_aa
40 i_box
41 i_box_filled
42 i_arc
18063344 43 i_circle_aa
dd55acc8 44
02d1d628
AMH
45 i_bezier_multi
46 i_poly_aa
47
48 i_copyto
49 i_rubthru
50 i_scaleaxis
51 i_scale_nn
52 i_haar
53 i_count_colors
dd55acc8 54
02d1d628
AMH
55 i_gaussian
56 i_conv
dd55acc8 57
f5991c03 58 i_convert
40eba1ea 59 i_map
dd55acc8 60
02d1d628
AMH
61 i_img_diff
62
63 i_init_fonts
64 i_t1_new
65 i_t1_destroy
66 i_t1_set_aa
67 i_t1_cp
68 i_t1_text
69 i_t1_bbox
70
02d1d628
AMH
71 i_tt_set_aa
72 i_tt_cp
73 i_tt_text
74 i_tt_bbox
75
02d1d628
AMH
76 i_readjpeg_wiol
77 i_writejpeg_wiol
78
79 i_readtiff_wiol
80 i_writetiff_wiol
d2dfdcc9 81 i_writetiff_wiol_faxable
02d1d628 82
790923a4
AMH
83 i_readpng_wiol
84 i_writepng_wiol
02d1d628
AMH
85
86 i_readgif
87 i_readgif_callback
88 i_writegif
89 i_writegifmc
90 i_writegif_gen
91 i_writegif_callback
92
93 i_readpnm_wiol
067d6bdc 94 i_writeppm_wiol
02d1d628 95
895dbd34
AMH
96 i_readraw_wiol
97 i_writeraw_wiol
02d1d628
AMH
98
99 i_contrast
100 i_hardinvert
101 i_noise
102 i_bumpmap
103 i_postlevels
104 i_mosaic
105 i_watermark
dd55acc8 106
02d1d628
AMH
107 malloc_state
108
109 list_formats
dd55acc8 110
02d1d628
AMH
111 i_gifquant
112
113 newfont
114 newcolor
115 newcolour
116 NC
117 NF
02d1d628
AMH
118);
119
02d1d628
AMH
120@EXPORT=qw(
121 init_log
122 i_list_formats
123 i_has_format
124 malloc_state
125 i_color_new
126
127 i_img_empty
128 i_img_empty_ch
129 );
130
131%EXPORT_TAGS=
132 (handy => [qw(
133 newfont
134 newcolor
135 NF
136 NC
137 )],
138 all => [@EXPORT_OK],
139 default => [qw(
140 load_plugin
141 unload_plugin
142 )]);
143
02d1d628
AMH
144BEGIN {
145 require Exporter;
146 require DynaLoader;
147
5b0d044f 148 $VERSION = '0.39pre1';
02d1d628
AMH
149 @ISA = qw(Exporter DynaLoader);
150 bootstrap Imager $VERSION;
151}
152
153BEGIN {
154 i_init_fonts(); # Initialize font engines
faa9b3e7 155 Imager::Font::__init();
02d1d628
AMH
156 for(i_list_formats()) { $formats{$_}++; }
157
158 if ($formats{'t1'}) {
159 i_t1_set_aa(1);
160 }
161
faa9b3e7
TC
162 if (!$formats{'t1'} and !$formats{'tt'}
163 && !$formats{'ft2'} && !$formats{'w32'}) {
02d1d628
AMH
164 $fontstate='no font support';
165 }
166
167 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
168
169 $DEBUG=0;
170
6607600c
TC
171 # the members of the subhashes under %filters are:
172 # callseq - a list of the parameters to the underlying filter in the
173 # order they are passed
174 # callsub - a code ref that takes a named parameter list and calls the
175 # underlying filter
176 # defaults - a hash of default values
177 # names - defines names for value of given parameters so if the names
178 # field is foo=> { bar=>1 }, and the user supplies "bar" as the
179 # foo parameter, the filter will receive 1 for the foo
180 # parameter
02d1d628
AMH
181 $filters{contrast}={
182 callseq => ['image','intensity'],
183 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
184 };
185
186 $filters{noise} ={
187 callseq => ['image', 'amount', 'subtype'],
188 defaults => { amount=>3,subtype=>0 },
189 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
190 };
191
192 $filters{hardinvert} ={
193 callseq => ['image'],
194 defaults => { },
195 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
196 };
197
198 $filters{autolevels} ={
199 callseq => ['image','lsat','usat','skew'],
200 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
201 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
202 };
203
204 $filters{turbnoise} ={
205 callseq => ['image'],
206 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
207 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
208 };
209
210 $filters{radnoise} ={
211 callseq => ['image'],
212 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
213 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
214 };
215
216 $filters{conv} ={
217 callseq => ['image', 'coef'],
218 defaults => { },
219 callsub => sub { my %hsh=@_; i_conv($hsh{image},$hsh{coef}); }
220 };
221
222 $filters{gradgen} ={
223 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
224 defaults => { },
225 callsub => sub { my %hsh=@_; i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
226 };
227
228 $filters{nearest_color} ={
229 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
230 defaults => { },
231 callsub => sub { my %hsh=@_; i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
232 };
faa9b3e7
TC
233 $filters{gaussian} = {
234 callseq => [ 'image', 'stddev' ],
235 defaults => { },
236 callsub => sub { my %hsh = @_; i_gaussian($hsh{image}, $hsh{stddev}); },
237 };
d08b8f85
TC
238 $filters{mosaic} =
239 {
240 callseq => [ qw(image size) ],
241 defaults => { size => 20 },
242 callsub => sub { my %hsh = @_; i_mosaic($hsh{image}, $hsh{size}) },
243 };
244 $filters{bumpmap} =
245 {
246 callseq => [ qw(image bump elevation lightx lighty st) ],
247 defaults => { elevation=>0, st=> 2 },
248 callsub => sub {
249 my %hsh = @_;
250 i_bumpmap($hsh{image}, $hsh{bump}{IMG}, $hsh{elevation},
251 $hsh{lightx}, $hsh{lighty}, $hsh{st});
252 },
253 };
254 $filters{postlevels} =
255 {
256 callseq => [ qw(image levels) ],
257 defaults => { levels => 10 },
258 callsub => sub { my %hsh = @_; i_postlevels($hsh{image}, $hsh{levels}); },
259 };
260 $filters{watermark} =
261 {
262 callseq => [ qw(image wmark tx ty pixdiff) ],
263 defaults => { pixdiff=>10, tx=>0, ty=>0 },
264 callsub =>
265 sub {
266 my %hsh = @_;
267 i_watermark($hsh{image}, $hsh{wmark}{IMG}, $hsh{tx}, $hsh{ty},
268 $hsh{pixdiff});
269 },
270 };
6607600c
TC
271 $filters{fountain} =
272 {
273 callseq => [ qw(image xa ya xb yb ftype repeat combine super_sample ssample_param segments) ],
274 names => {
275 ftype => { linear => 0,
276 bilinear => 1,
277 radial => 2,
278 radial_square => 3,
279 revolution => 4,
280 conical => 5 },
281 repeat => { none => 0,
282 sawtooth => 1,
283 triangle => 2,
284 saw_both => 3,
285 tri_both => 4,
286 },
287 super_sample => {
288 none => 0,
289 grid => 1,
290 random => 2,
291 circle => 3,
292 },
293 },
294 defaults => { ftype => 0, repeat => 0, combine => 0,
295 super_sample => 0, ssample_param => 4,
296 segments=>[
297 [ 0, 0.5, 1,
298 Imager::Color->new(0,0,0),
299 Imager::Color->new(255, 255, 255),
300 0, 0,
301 ],
302 ],
303 },
304 callsub =>
305 sub {
306 my %hsh = @_;
307 i_fountain($hsh{image}, $hsh{xa}, $hsh{ya}, $hsh{xb}, $hsh{yb},
308 $hsh{ftype}, $hsh{repeat}, $hsh{combine}, $hsh{super_sample},
309 $hsh{ssample_param}, $hsh{segments});
310 },
311 };
02d1d628
AMH
312
313 $FORMATGUESS=\&def_guess_type;
314}
315
316#
317# Non methods
318#
319
320# initlize Imager
321# NOTE: this might be moved to an import override later on
322
323#sub import {
324# my $pack = shift;
325# (look through @_ for special tags, process, and remove them);
326# use Data::Dumper;
327# print Dumper($pack);
328# print Dumper(@_);
329#}
330
331sub init {
332 my %parms=(loglevel=>1,@_);
333 if ($parms{'log'}) {
334 init_log($parms{'log'},$parms{'loglevel'});
335 }
336
337# if ($parms{T1LIB_CONFIG}) { $ENV{T1LIB_CONFIG}=$parms{T1LIB_CONFIG}; }
338# if ( $ENV{T1LIB_CONFIG} and ( $fontstate eq 'missing conf' )) {
339# i_init_fonts();
340# $fontstate='ok';
341# }
342}
343
344END {
345 if ($DEBUG) {
346 print "shutdown code\n";
347 # for(keys %instances) { $instances{$_}->DESTROY(); }
348 malloc_state(); # how do decide if this should be used? -- store something from the import
349 print "Imager exiting\n";
350 }
351}
352
353# Load a filter plugin
354
355sub load_plugin {
356 my ($filename)=@_;
357 my $i;
358 my ($DSO_handle,$str)=DSO_open($filename);
359 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
360 my %funcs=DSO_funclist($DSO_handle);
361 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
362 $i=0;
363 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
364
365 $DSOs{$filename}=[$DSO_handle,\%funcs];
366
367 for(keys %funcs) {
368 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
369 $DEBUG && print "eval string:\n",$evstr,"\n";
370 eval $evstr;
371 print $@ if $@;
372 }
373 return 1;
374}
375
376# Unload a plugin
377
378sub unload_plugin {
379 my ($filename)=@_;
380
381 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
382 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
383 for(keys %{$funcref}) {
384 delete $filters{$_};
385 $DEBUG && print "unloading: $_\n";
386 }
387 my $rc=DSO_close($DSO_handle);
388 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
389 return 1;
390}
391
64606cc7
TC
392# take the results of i_error() and make a message out of it
393sub _error_as_msg {
394 return join(": ", map $_->[0], i_errors());
395}
396
02d1d628
AMH
397#
398# Methods to be called on objects.
399#
400
401# Create a new Imager object takes very few parameters.
402# usually you call this method and then call open from
403# the resulting object
404
405sub new {
406 my $class = shift;
407 my $self ={};
408 my %hsh=@_;
409 bless $self,$class;
410 $self->{IMG}=undef; # Just to indicate what exists
411 $self->{ERRSTR}=undef; #
412 $self->{DEBUG}=$DEBUG;
413 $self->{DEBUG} && print "Initialized Imager\n";
414 if ($hsh{xsize} && $hsh{ysize}) { $self->img_set(%hsh); }
415 return $self;
416}
417
02d1d628
AMH
418# Copy an entire image with no changes
419# - if an image has magic the copy of it will not be magical
420
421sub copy {
422 my $self = shift;
423 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
424
425 my $newcopy=Imager->new();
426 $newcopy->{IMG}=i_img_new();
427 i_copy($newcopy->{IMG},$self->{IMG});
428 return $newcopy;
429}
430
431# Paste a region
432
433sub paste {
434 my $self = shift;
435 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
436 my %input=(left=>0, top=>0, @_);
437 unless($input{img}) {
438 $self->{ERRSTR}="no source image";
439 return;
440 }
441 $input{left}=0 if $input{left} <= 0;
442 $input{top}=0 if $input{top} <= 0;
443 my $src=$input{img};
444 my($r,$b)=i_img_info($src->{IMG});
445
446 i_copyto($self->{IMG}, $src->{IMG},
447 0,0, $r, $b, $input{left}, $input{top});
448 return $self; # What should go here??
449}
450
451# Crop an image - i.e. return a new image that is smaller
452
453sub crop {
454 my $self=shift;
455 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
456 my %hsh=(left=>0,right=>0,top=>0,bottom=>0,@_);
457
458 my ($w,$h,$l,$r,$b,$t)=($self->getwidth(),$self->getheight(),
459 @hsh{qw(left right bottom top)});
460 $l=0 if not defined $l;
461 $t=0 if not defined $t;
299a3866
AMH
462
463 $r||=$l+delete $hsh{'width'} if defined $l and exists $hsh{'width'};
464 $b||=$t+delete $hsh{'height'} if defined $t and exists $hsh{'height'};
465 $l||=$r-delete $hsh{'width'} if defined $r and exists $hsh{'width'};
466 $t||=$b-delete $hsh{'height'} if defined $b and exists $hsh{'height'};
467
02d1d628
AMH
468 $r=$self->getwidth if not defined $r;
469 $b=$self->getheight if not defined $b;
470
471 ($l,$r)=($r,$l) if $l>$r;
472 ($t,$b)=($b,$t) if $t>$b;
473
299a3866
AMH
474 if ($hsh{'width'}) {
475 $l=int(0.5+($w-$hsh{'width'})/2);
476 $r=$l+$hsh{'width'};
02d1d628
AMH
477 } else {
478 $hsh{'width'}=$r-$l;
479 }
299a3866
AMH
480 if ($hsh{'height'}) {
481 $b=int(0.5+($h-$hsh{'height'})/2);
482 $t=$h+$hsh{'height'};
02d1d628
AMH
483 } else {
484 $hsh{'height'}=$b-$t;
485 }
486
487# print "l=$l, r=$r, h=$hsh{'width'}\n";
488# print "t=$t, b=$b, w=$hsh{'height'}\n";
489
299a3866 490 my $dst=Imager->new(xsize=>$hsh{'width'}, ysize=>$hsh{'height'}, channels=>$self->getchannels());
02d1d628
AMH
491
492 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
493 return $dst;
494}
495
496# Sets an image to a certain size and channel number
497# if there was previously data in the image it is discarded
498
499sub img_set {
500 my $self=shift;
501
faa9b3e7 502 my %hsh=(xsize=>100, ysize=>100, channels=>3, bits=>8, type=>'direct', @_);
02d1d628
AMH
503
504 if (defined($self->{IMG})) {
faa9b3e7
TC
505 # let IIM_DESTROY destroy it, it's possible this image is
506 # referenced from a virtual image (like masked)
507 #i_img_destroy($self->{IMG});
02d1d628
AMH
508 undef($self->{IMG});
509 }
510
faa9b3e7
TC
511 if ($hsh{type} eq 'paletted' || $hsh{type} eq 'pseudo') {
512 $self->{IMG} = i_img_pal_new($hsh{xsize}, $hsh{ysize}, $hsh{channels},
513 $hsh{maxcolors} || 256);
514 }
515 elsif ($hsh{bits} == 16) {
516 $self->{IMG} = i_img_16_new($hsh{xsize}, $hsh{ysize}, $hsh{channels});
517 }
518 else {
519 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'}, $hsh{'ysize'},
520 $hsh{'channels'});
521 }
522}
523
524# created a masked version of the current image
525sub masked {
526 my $self = shift;
527
528 $self or return undef;
529 my %opts = (left => 0,
530 top => 0,
531 right => $self->getwidth,
532 bottom => $self->getheight,
533 @_);
534 my $mask = $opts{mask} ? $opts{mask}{IMG} : undef;
535
536 my $result = Imager->new;
537 $result->{IMG} = i_img_masked_new($self->{IMG}, $mask, $opts{left},
538 $opts{top}, $opts{right} - $opts{left},
539 $opts{bottom} - $opts{top});
540 # keep references to the mask and base images so they don't
541 # disappear on us
542 $result->{DEPENDS} = [ $self->{IMG}, $mask ];
543
544 $result;
545}
546
547# convert an RGB image into a paletted image
548sub to_paletted {
549 my $self = shift;
550 my $opts;
551 if (@_ != 1 && !ref $_[0]) {
552 $opts = { @_ };
553 }
554 else {
555 $opts = shift;
556 }
557
558 my $result = Imager->new;
559 $result->{IMG} = i_img_to_pal($self->{IMG}, $opts);
560
561 #print "Type ", i_img_type($result->{IMG}), "\n";
562
563 $result->{IMG} or undef $result;
564
565 return $result;
566}
567
568# convert a paletted (or any image) to an 8-bit/channel RGB images
569sub to_rgb8 {
570 my $self = shift;
571 my $result;
572
573 if ($self->{IMG}) {
574 $result = Imager->new;
575 $result->{IMG} = i_img_to_rgb($self->{IMG})
576 or undef $result;
577 }
578
579 return $result;
580}
581
582sub addcolors {
583 my $self = shift;
584 my %opts = (colors=>[], @_);
585
586 @{$opts{colors}} or return undef;
587
588 $self->{IMG} and i_addcolors($self->{IMG}, @{$opts{colors}});
589}
590
591sub setcolors {
592 my $self = shift;
593 my %opts = (start=>0, colors=>[], @_);
594 @{$opts{colors}} or return undef;
595
596 $self->{IMG} and i_setcolors($self->{IMG}, $opts{start}, @{$opts{colors}});
597}
598
599sub getcolors {
600 my $self = shift;
601 my %opts = @_;
602 if (!exists $opts{start} && !exists $opts{count}) {
603 # get them all
604 $opts{start} = 0;
605 $opts{count} = $self->colorcount;
606 }
607 elsif (!exists $opts{count}) {
608 $opts{count} = 1;
609 }
610 elsif (!exists $opts{start}) {
611 $opts{start} = 0;
612 }
613
614 $self->{IMG} and
615 return i_getcolors($self->{IMG}, $opts{start}, $opts{count});
616}
617
618sub colorcount {
619 i_colorcount($_[0]{IMG});
620}
621
622sub maxcolors {
623 i_maxcolors($_[0]{IMG});
624}
625
626sub findcolor {
627 my $self = shift;
628 my %opts = @_;
629 $opts{color} or return undef;
630
631 $self->{IMG} and i_findcolor($self->{IMG}, $opts{color});
632}
633
634sub bits {
635 my $self = shift;
636 $self->{IMG} and i_img_bits($self->{IMG});
637}
638
639sub type {
640 my $self = shift;
641 if ($self->{IMG}) {
642 return i_img_type($self->{IMG}) ? "paletted" : "direct";
643 }
644}
645
646sub virtual {
647 my $self = shift;
648 $self->{IMG} and i_img_virtual($self->{IMG});
649}
650
651sub tags {
652 my ($self, %opts) = @_;
653
654 $self->{IMG} or return;
655
656 if (defined $opts{name}) {
657 my @result;
658 my $start = 0;
659 my $found;
660 while (defined($found = i_tags_find($self->{IMG}, $opts{name}, $start))) {
661 push @result, (i_tags_get($self->{IMG}, $found))[1];
662 $start = $found+1;
663 }
664 return wantarray ? @result : $result[0];
665 }
666 elsif (defined $opts{code}) {
667 my @result;
668 my $start = 0;
669 my $found;
670 while (defined($found = i_tags_findn($self->{IMG}, $opts{code}, $start))) {
671 push @result, (i_tags_get($self->{IMG}, $found))[1];
672 $start = $found+1;
673 }
674 return @result;
675 }
676 else {
677 if (wantarray) {
678 return map { [ i_tags_get($self->{IMG}, $_) ] } 0.. i_tags_count($self->{IMG})-1;
679 }
680 else {
681 return i_tags_count($self->{IMG});
682 }
683 }
684}
685
686sub addtag {
687 my $self = shift;
688 my %opts = @_;
689
690 return -1 unless $self->{IMG};
691 if ($opts{name}) {
692 if (defined $opts{value}) {
693 if ($opts{value} =~ /^\d+$/) {
694 # add as a number
695 return i_tags_addn($self->{IMG}, $opts{name}, 0, $opts{value});
696 }
697 else {
698 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{value}, 0);
699 }
700 }
701 elsif (defined $opts{data}) {
702 # force addition as a string
703 return i_tags_add($self->{IMG}, $opts{name}, 0, $opts{data}, 0);
704 }
705 else {
706 $self->{ERRSTR} = "No value supplied";
707 return undef;
708 }
709 }
710 elsif ($opts{code}) {
711 if (defined $opts{value}) {
712 if ($opts{value} =~ /^\d+$/) {
713 # add as a number
714 return i_tags_addn($self->{IMG}, $opts{code}, 0, $opts{value});
715 }
716 else {
717 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{value}, 0);
718 }
719 }
720 elsif (defined $opts{data}) {
721 # force addition as a string
722 return i_tags_add($self->{IMG}, $opts{code}, 0, $opts{data}, 0);
723 }
724 else {
725 $self->{ERRSTR} = "No value supplied";
726 return undef;
727 }
728 }
729 else {
730 return undef;
731 }
732}
733
734sub deltag {
735 my $self = shift;
736 my %opts = @_;
737
738 return 0 unless $self->{IMG};
739
740 if (defined $opts{index}) {
741 return i_tags_delete($self->{IMG}, $opts{index});
742 }
743 elsif (defined $opts{name}) {
744 return i_tags_delbyname($self->{IMG}, $opts{name});
745 }
746 elsif (defined $opts{code}) {
747 return i_tags_delbycode($self->{IMG}, $opts{code});
748 }
749 else {
750 $self->{ERRSTR} = "Need to supply index, name, or code parameter";
751 return 0;
752 }
02d1d628
AMH
753}
754
755# Read an image from file
756
757sub read {
758 my $self = shift;
759 my %input=@_;
760 my ($fh, $fd, $IO);
761
762 if (defined($self->{IMG})) {
faa9b3e7
TC
763 # let IIM_DESTROY do the destruction, since the image may be
764 # referenced from elsewhere
765 #i_img_destroy($self->{IMG});
02d1d628
AMH
766 undef($self->{IMG});
767 }
768
895dbd34
AMH
769 if (!$input{fd} and !$input{file} and !$input{data}) {
770 $self->{ERRSTR}='no file, fd or data parameter'; return undef;
771 }
02d1d628
AMH
772 if ($input{file}) {
773 $fh = new IO::File($input{file},"r");
895dbd34
AMH
774 if (!defined $fh) {
775 $self->{ERRSTR}='Could not open file'; return undef;
776 }
02d1d628
AMH
777 binmode($fh);
778 $fd = $fh->fileno();
779 }
895dbd34
AMH
780 if ($input{fd}) {
781 $fd=$input{fd};
782 }
02d1d628
AMH
783
784 # FIXME: Find the format here if not specified
785 # yes the code isn't here yet - next week maybe?
dd55acc8
AMH
786 # Next week? Are you high or something? That comment
787 # has been there for half a year dude.
cf692b64 788 # Look, i just work here, ok?
02d1d628 789
895dbd34
AMH
790 if (!$input{type} and $input{file}) {
791 $input{type}=$FORMATGUESS->($input{file});
792 }
793 if (!$formats{$input{type}}) {
794 $self->{ERRSTR}='format not supported'; return undef;
795 }
02d1d628 796
705fd961 797 my %iolready=(jpeg=>1, png=>1, tiff=>1, pnm=>1, raw=>1, bmp=>1);
02d1d628
AMH
798
799 if ($iolready{$input{type}}) {
800 # Setup data source
895dbd34 801 $IO = io_new_fd($fd); # sort of simple for now eh?
02d1d628
AMH
802
803 if ( $input{type} eq 'jpeg' ) {
804 ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_wiol( $IO );
895dbd34
AMH
805 if ( !defined($self->{IMG}) ) {
806 $self->{ERRSTR}='unable to read jpeg image'; return undef;
807 }
02d1d628
AMH
808 $self->{DEBUG} && print "loading a jpeg file\n";
809 return $self;
810 }
811
812 if ( $input{type} eq 'tiff' ) {
813 $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
895dbd34
AMH
814 if ( !defined($self->{IMG}) ) {
815 $self->{ERRSTR}='unable to read tiff image'; return undef;
816 }
02d1d628
AMH
817 $self->{DEBUG} && print "loading a tiff file\n";
818 return $self;
819 }
820
821 if ( $input{type} eq 'pnm' ) {
822 $self->{IMG}=i_readpnm_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
895dbd34
AMH
823 if ( !defined($self->{IMG}) ) {
824 $self->{ERRSTR}='unable to read pnm image: '._error_as_msg(); return undef;
825 }
02d1d628
AMH
826 $self->{DEBUG} && print "loading a pnm file\n";
827 return $self;
828 }
829
790923a4
AMH
830 if ( $input{type} eq 'png' ) {
831 $self->{IMG}=i_readpng_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
832 if ( !defined($self->{IMG}) ) {
833 $self->{ERRSTR}='unable to read png image';
834 return undef;
835 }
836 $self->{DEBUG} && print "loading a png file\n";
837 }
838
705fd961
TC
839 if ( $input{type} eq 'bmp' ) {
840 $self->{IMG}=i_readbmp_wiol( $IO );
841 if ( !defined($self->{IMG}) ) {
842 $self->{ERRSTR}='unable to read bmp image';
843 return undef;
844 }
845 $self->{DEBUG} && print "loading a bmp file\n";
846 }
847
895dbd34
AMH
848 if ( $input{type} eq 'raw' ) {
849 my %params=(datachannels=>3,storechannels=>3,interleave=>1,%input);
02d1d628 850
895dbd34
AMH
851 if ( !($params{xsize} && $params{ysize}) ) {
852 $self->{ERRSTR}='missing xsize or ysize parameter for raw';
853 return undef;
854 }
02d1d628 855
895dbd34
AMH
856 $self->{IMG} = i_readraw_wiol( $IO,
857 $params{xsize},
858 $params{ysize},
859 $params{datachannels},
860 $params{storechannels},
861 $params{interleave});
862 if ( !defined($self->{IMG}) ) {
863 $self->{ERRSTR}='unable to read raw image';
864 return undef;
865 }
866 $self->{DEBUG} && print "loading a raw file\n";
867 }
790923a4 868
895dbd34 869 } else {
02d1d628 870
895dbd34 871 # Old code for reference while changing the new stuff
02d1d628 872
895dbd34
AMH
873 if (!$input{type} and $input{file}) {
874 $input{type}=$FORMATGUESS->($input{file});
875 }
876
877 if (!$input{type}) {
878 $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef;
879 }
02d1d628 880
895dbd34
AMH
881 if (!$formats{$input{type}}) {
882 $self->{ERRSTR}='format not supported';
a59ffd27
TC
883 return undef;
884 }
895dbd34
AMH
885
886 if ($input{file}) {
887 $fh = new IO::File($input{file},"r");
888 if (!defined $fh) {
889 $self->{ERRSTR}='Could not open file';
890 return undef;
a59ffd27 891 }
895dbd34
AMH
892 binmode($fh);
893 $fd = $fh->fileno();
a59ffd27 894 }
895dbd34
AMH
895
896 if ($input{fd}) {
897 $fd=$input{fd};
898 }
899
900 if ( $input{type} eq 'gif' ) {
901 my $colors;
902 if ($input{colors} && !ref($input{colors})) {
903 # must be a reference to a scalar that accepts the colour map
904 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
905 return undef;
a59ffd27 906 }
895dbd34
AMH
907 if (exists $input{data}) {
908 if ($input{colors}) {
909 ($self->{IMG}, $colors) = i_readgif_scalar($input{data});
910 } else {
911 $self->{IMG}=i_readgif_scalar($input{data});
912 }
913 } else {
914 if ($input{colors}) {
915 ($self->{IMG}, $colors) = i_readgif( $fd );
916 } else {
917 $self->{IMG} = i_readgif( $fd )
918 }
a59ffd27 919 }
895dbd34
AMH
920 if ($colors) {
921 # we may or may not change i_readgif to return blessed objects...
922 ${ $input{colors} } = [ map { NC(@$_) } @$colors ];
923 }
924 if ( !defined($self->{IMG}) ) {
925 $self->{ERRSTR}= 'reading GIF:'._error_as_msg();
926 return undef;
927 }
928 $self->{DEBUG} && print "loading a gif file\n";
dd55acc8 929 }
02d1d628
AMH
930 }
931 return $self;
02d1d628
AMH
932}
933
02d1d628 934# Write an image to file
02d1d628
AMH
935sub write {
936 my $self = shift;
4c2d6970
TC
937 my %input=(jpegquality=>75, gifquant=>'mc', lmdither=>6.0, lmfixed=>[],
938 fax_fine=>1, @_);
02d1d628
AMH
939 my ($fh, $rc, $fd, $IO);
940
cf692b64 941 my %iolready=( tiff=>1, raw=>1, png=>1, pnm=>1, bmp=>1, jpeg=>1 ); # this will be SO MUCH BETTER once they are all in there
02d1d628
AMH
942
943 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
944
945 if (!$input{file} and !$input{'fd'} and !$input{'data'}) { $self->{ERRSTR}='file/fd/data parameter missing'; return undef; }
4c2d6970 946 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
02d1d628
AMH
947 if (!$input{type}) { $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef; }
948
949 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
950
951 if (exists $input{'fd'}) {
952 $fd=$input{'fd'};
953 } elsif (exists $input{'data'}) {
954 $IO = Imager::io_new_bufchain();
955 } else {
956 $fh = new IO::File($input{file},"w+");
957 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
faa9b3e7 958 binmode($fh) or die;
02d1d628
AMH
959 $fd = $fh->fileno();
960 }
961
02d1d628 962 if ($iolready{$input{type}}) {
4c2d6970 963 if (defined $fd) {
02d1d628
AMH
964 $IO = io_new_fd($fd);
965 }
966
967 if ($input{type} eq 'tiff') {
4c2d6970
TC
968 if (defined $input{class} && $input{class} eq 'fax') {
969 if (!i_writetiff_wiol_faxable($self->{IMG}, $IO, $input{fax_fine})) {
d2dfdcc9
TC
970 $self->{ERRSTR}='Could not write to buffer';
971 return undef;
972 }
04418ecc 973 } else {
930c67c8
AMH
974 if (!i_writetiff_wiol($self->{IMG}, $IO)) {
975 $self->{ERRSTR}='Could not write to buffer';
976 return undef;
d2dfdcc9
TC
977 }
978 }
04418ecc 979 } elsif ( $input{type} eq 'pnm' ) {
04418ecc
AMH
980 if ( ! i_writeppm_wiol($self->{IMG},$IO) ) {
981 $self->{ERRSTR}='unable to write pnm image';
982 return undef;
983 }
984 $self->{DEBUG} && print "writing a pnm file\n";
985 } elsif ( $input{type} eq 'raw' ) {
ec9b9c3e 986 if ( !i_writeraw_wiol($self->{IMG},$IO) ) {
04418ecc
AMH
987 $self->{ERRSTR}='unable to write raw image';
988 return undef;
989 }
990 $self->{DEBUG} && print "writing a raw file\n";
ec9b9c3e
AMH
991 } elsif ( $input{type} eq 'png' ) {
992 if ( !i_writepng_wiol($self->{IMG}, $IO) ) {
993 $self->{ERRSTR}='unable to write png image';
994 return undef;
995 }
996 $self->{DEBUG} && print "writing a png file\n";
cf692b64
TC
997 } elsif ( $input{type} eq 'jpeg' ) {
998 if ( !i_writejpeg_wiol($self->{IMG}, $IO, $input{jpegquality})) {
999 $self->{ERRSTR}='unable to write jpeg image';
1000 return undef;
1001 }
1002 $self->{DEBUG} && print "writing a jpeg file\n";
705fd961
TC
1003 } elsif ( $input{type} eq 'bmp' ) {
1004 if ( !i_writebmp_wiol($self->{IMG}, $IO) ) {
1005 $self->{ERRSTR}='unable to write bmp image';
1006 return undef;
1007 }
1008 $self->{DEBUG} && print "writing a bmp file\n";
02d1d628
AMH
1009 }
1010
930c67c8
AMH
1011 if (exists $input{'data'}) {
1012 my $data = io_slurp($IO);
1013 if (!$data) {
1014 $self->{ERRSTR}='Could not slurp from buffer';
1015 return undef;
1016 }
1017 ${$input{data}} = $data;
1018 }
02d1d628
AMH
1019 return $self;
1020 } else {
02d1d628
AMH
1021 if ( $input{type} eq 'gif' ) {
1022 if (not $input{gifplanes}) {
1023 my $gp;
1024 my $count=i_count_colors($self->{IMG}, 256);
1025 $gp=8 if $count == -1;
1026 $gp=1 if not $gp and $count <= 2;
1027 $gp=2 if not $gp and $count <= 4;
1028 $gp=3 if not $gp and $count <= 8;
1029 $gp=4 if not $gp and $count <= 16;
1030 $gp=5 if not $gp and $count <= 32;
1031 $gp=6 if not $gp and $count <= 64;
1032 $gp=7 if not $gp and $count <= 128;
1033 $input{gifplanes} = $gp || 8;
1034 }
1035
1036 if ($input{gifplanes}>8) {
1037 $input{gifplanes}=8;
1038 }
1039 if ($input{gifquant} eq 'gen' || $input{callback}) {
1040
1041
1042 if ($input{gifquant} eq 'lm') {
1043
1044 $input{make_colors} = 'addi';
1045 $input{translate} = 'perturb';
1046 $input{perturb} = $input{lmdither};
1047 } elsif ($input{gifquant} eq 'gen') {
1048 # just pass options through
1049 } else {
1050 $input{make_colors} = 'webmap'; # ignored
1051 $input{translate} = 'giflib';
1052 }
1053
1054 if ($input{callback}) {
1055 defined $input{maxbuffer} or $input{maxbuffer} = -1;
1056 $rc = i_writegif_callback($input{callback}, $input{maxbuffer},
1057 \%input, $self->{IMG});
1058 } else {
1059 $rc = i_writegif_gen($fd, \%input, $self->{IMG});
1060 }
1061
02d1d628
AMH
1062 } elsif ($input{gifquant} eq 'lm') {
1063 $rc=i_writegif($self->{IMG},$fd,$input{gifplanes},$input{lmdither},$input{lmfixed});
1064 } else {
1065 $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes});
1066 }
1067 if ( !defined($rc) ) {
3827fae0 1068 $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef;
02d1d628
AMH
1069 }
1070 $self->{DEBUG} && print "writing a gif file\n";
1071
02d1d628 1072 }
02d1d628
AMH
1073 }
1074 return $self;
1075}
1076
1077sub write_multi {
1078 my ($class, $opts, @images) = @_;
1079
1080 if ($opts->{type} eq 'gif') {
ed88b092
TC
1081 my $gif_delays = $opts->{gif_delays};
1082 local $opts->{gif_delays} = $gif_delays;
1083 unless (ref $opts->{gif_delays}) {
1084 # assume the caller wants the same delay for each frame
1085 $opts->{gif_delays} = [ ($gif_delays) x @images ];
1086 }
02d1d628
AMH
1087 # translate to ImgRaw
1088 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
1089 $ERRSTR = "Usage: Imager->write_multi({ options }, @images)";
1090 return 0;
1091 }
1092 my @work = map $_->{IMG}, @images;
1093 if ($opts->{callback}) {
1094 # Note: you may need to fix giflib for this one to work
1095 my $maxbuffer = $opts->{maxbuffer};
1096 defined $maxbuffer or $maxbuffer = -1; # max by default
1097 return i_writegif_callback($opts->{callback}, $maxbuffer,
1098 $opts, @work);
1099 }
1100 if ($opts->{fd}) {
1101 return i_writegif_gen($opts->{fd}, $opts, @work);
1102 }
1103 else {
1104 my $fh = IO::File->new($opts->{file}, "w+");
1105 unless ($fh) {
1106 $ERRSTR = "Error creating $opts->{file}: $!";
1107 return 0;
1108 }
1109 binmode($fh);
1110 return i_writegif_gen(fileno($fh), $opts, @work);
1111 }
1112 }
1113 else {
1114 $ERRSTR = "Sorry, write_multi doesn't support $opts->{type} yet";
1115 return 0;
1116 }
1117}
1118
faa9b3e7
TC
1119# read multiple images from a file
1120sub read_multi {
1121 my ($class, %opts) = @_;
1122
1123 if ($opts{file} && !exists $opts{type}) {
1124 # guess the type
1125 my $type = $FORMATGUESS->($opts{file});
1126 $opts{type} = $type;
1127 }
1128 unless ($opts{type}) {
1129 $ERRSTR = "No type parameter supplied and it couldn't be guessed";
1130 return;
1131 }
1132 my $fd;
1133 my $file;
1134 if ($opts{file}) {
1135 $file = IO::File->new($opts{file}, "r");
1136 unless ($file) {
1137 $ERRSTR = "Could not open file $opts{file}: $!";
1138 return;
1139 }
1140 binmode $file;
1141 $fd = fileno($file);
1142 }
1143 elsif ($opts{fh}) {
1144 $fd = fileno($opts{fh});
1145 unless ($fd) {
1146 $ERRSTR = "File handle specified with fh option not open";
1147 return;
1148 }
1149 }
1150 elsif ($opts{fd}) {
1151 $fd = $opts{fd};
1152 }
1153 elsif ($opts{callback} || $opts{data}) {
1154 # don't fail here
1155 }
1156 else {
1157 $ERRSTR = "You need to specify one of file, fd, fh, callback or data";
1158 return;
1159 }
1160
1161 if ($opts{type} eq 'gif') {
1162 my @imgs;
1163 if ($fd) {
1164 @imgs = i_readgif_multi($fd);
1165 }
1166 else {
1167 if (Imager::i_giflib_version() < 4.0) {
1168 $ERRSTR = "giflib3.x does not support callbacks";
1169 return;
1170 }
1171 if ($opts{callback}) {
1172 @imgs = i_readgif_multi_callback($opts{callback})
1173 }
1174 else {
1175 @imgs = i_readgif_multi_scalar($opts{data});
1176 }
1177 }
1178 if (@imgs) {
1179 return map {
1180 bless { IMG=>$_, DEBUG=>$DEBUG, ERRSTR=>undef }, 'Imager'
1181 } @imgs;
1182 }
1183 else {
1184 $ERRSTR = _error_as_msg();
1185 return;
1186 }
1187 }
1188
1189 $ERRSTR = "Cannot read multiple images from $opts{type} files";
1190 return;
1191}
1192
02d1d628
AMH
1193# Destroy an Imager object
1194
1195sub DESTROY {
1196 my $self=shift;
1197 # delete $instances{$self};
1198 if (defined($self->{IMG})) {
faa9b3e7
TC
1199 # the following is now handled by the XS DESTROY method for
1200 # Imager::ImgRaw object
1201 # Re-enabling this will break virtual images
1202 # tested for in t/t020masked.t
1203 # i_img_destroy($self->{IMG});
02d1d628
AMH
1204 undef($self->{IMG});
1205 } else {
1206# print "Destroy Called on an empty image!\n"; # why did I put this here??
1207 }
1208}
1209
1210# Perform an inplace filter of an image
1211# that is the image will be overwritten with the data
1212
1213sub filter {
1214 my $self=shift;
1215 my %input=@_;
1216 my %hsh;
1217 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1218
1219 if (!$input{type}) { $self->{ERRSTR}='type parameter missing'; return undef; }
1220
1221 if ( (grep { $_ eq $input{type} } keys %filters) != 1) {
1222 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
1223 }
1224
6607600c
TC
1225 if ($filters{$input{type}}{names}) {
1226 my $names = $filters{$input{type}}{names};
1227 for my $name (keys %$names) {
1228 if (defined $input{$name} && exists $names->{$name}{$input{$name}}) {
1229 $input{$name} = $names->{$name}{$input{$name}};
1230 }
1231 }
1232 }
02d1d628
AMH
1233 if (defined($filters{$input{type}}{defaults})) {
1234 %hsh=('image',$self->{IMG},%{$filters{$input{type}}{defaults}},%input);
1235 } else {
1236 %hsh=('image',$self->{IMG},%input);
1237 }
1238
1239 my @cs=@{$filters{$input{type}}{callseq}};
1240
1241 for(@cs) {
1242 if (!defined($hsh{$_})) {
1243 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{type}; return undef;
1244 }
1245 }
1246
1247 &{$filters{$input{type}}{callsub}}(%hsh);
1248
1249 my @b=keys %hsh;
1250
1251 $self->{DEBUG} && print "callseq is: @cs\n";
1252 $self->{DEBUG} && print "matching callseq is: @b\n";
1253
1254 return $self;
1255}
1256
1257# Scale an image to requested size and return the scaled version
1258
1259sub scale {
1260 my $self=shift;
1261 my %opts=(scalefactor=>0.5,type=>'max',qtype=>'normal',@_);
1262 my $img = Imager->new();
1263 my $tmp = Imager->new();
1264
1265 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1266
1267 if ($opts{xpixels} and $opts{ypixels} and $opts{type}) {
1268 my ($xpix,$ypix)=( $opts{xpixels}/$self->getwidth() , $opts{ypixels}/$self->getheight() );
1269 if ($opts{type} eq 'min') { $opts{scalefactor}=min($xpix,$ypix); }
1270 if ($opts{type} eq 'max') { $opts{scalefactor}=max($xpix,$ypix); }
1271 } elsif ($opts{xpixels}) { $opts{scalefactor}=$opts{xpixels}/$self->getwidth(); }
1272 elsif ($opts{ypixels}) { $opts{scalefactor}=$opts{ypixels}/$self->getheight(); }
1273
1274 if ($opts{qtype} eq 'normal') {
1275 $tmp->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
1276 if ( !defined($tmp->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1277 $img->{IMG}=i_scaleaxis($tmp->{IMG},$opts{scalefactor},1);
1278 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1279 return $img;
1280 }
1281 if ($opts{'qtype'} eq 'preview') {
1282 $img->{IMG}=i_scale_nn($self->{IMG},$opts{'scalefactor'},$opts{'scalefactor'});
1283 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1284 return $img;
1285 }
1286 $self->{ERRSTR}='scale: invalid value for qtype'; return undef;
1287}
1288
1289# Scales only along the X axis
1290
1291sub scaleX {
1292 my $self=shift;
1293 my %opts=(scalefactor=>0.5,@_);
1294
1295 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1296
1297 my $img = Imager->new();
1298
1299 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getwidth(); }
1300
1301 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1302 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
1303
1304 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1305 return $img;
1306}
1307
1308# Scales only along the Y axis
1309
1310sub scaleY {
1311 my $self=shift;
1312 my %opts=(scalefactor=>0.5,@_);
1313
1314 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1315
1316 my $img = Imager->new();
1317
1318 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getheight(); }
1319
1320 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1321 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},1);
1322
1323 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
1324 return $img;
1325}
1326
1327
1328# Transform returns a spatial transformation of the input image
1329# this moves pixels to a new location in the returned image.
1330# NOTE - should make a utility function to check transforms for
1331# stack overruns
1332
1333sub transform {
1334 my $self=shift;
1335 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1336 my %opts=@_;
1337 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
1338
1339# print Dumper(\%opts);
1340# xopcopdes
1341
1342 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
1343 if (!$I2P) {
1344 eval ("use Affix::Infix2Postfix;");
1345 print $@;
1346 if ( $@ ) {
1347 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
1348 return undef;
1349 }
1350 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
1351 {op=>'-',trans=>'Sub'},
1352 {op=>'*',trans=>'Mult'},
1353 {op=>'/',trans=>'Div'},
1354 {op=>'-',type=>'unary',trans=>'u-'},
1355 {op=>'**'},
1356 {op=>'func',type=>'unary'}],
1357 'grouping'=>[qw( \( \) )],
1358 'func'=>[qw( sin cos )],
1359 'vars'=>[qw( x y )]
1360 );
1361 }
1362
1363 @xt=$I2P->translate($opts{'xexpr'});
1364 @yt=$I2P->translate($opts{'yexpr'});
1365
1366 $numre=$I2P->{'numre'};
1367 @pt=(0,0);
1368
1369 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
1370 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
1371 @{$opts{'parm'}}=@pt;
1372 }
1373
1374# print Dumper(\%opts);
1375
1376 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
1377 $self->{ERRSTR}='transform: no xopcodes given.';
1378 return undef;
1379 }
1380
1381 @op=@{$opts{'xopcodes'}};
1382 for $iop (@op) {
1383 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
1384 $self->{ERRSTR}="transform: illegal opcode '$_'.";
1385 return undef;
1386 }
1387 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
1388 }
1389
1390
1391# yopcopdes
1392
1393 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
1394 $self->{ERRSTR}='transform: no yopcodes given.';
1395 return undef;
1396 }
1397
1398 @op=@{$opts{'yopcodes'}};
1399 for $iop (@op) {
1400 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
1401 $self->{ERRSTR}="transform: illegal opcode '$_'.";
1402 return undef;
1403 }
1404 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
1405 }
1406
1407#parameters
1408
1409 if ( !exists $opts{'parm'}) {
1410 $self->{ERRSTR}='transform: no parameter arg given.';
1411 return undef;
1412 }
1413
1414# print Dumper(\@ropx);
1415# print Dumper(\@ropy);
1416# print Dumper(\@ropy);
1417
1418 my $img = Imager->new();
1419 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
1420 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
1421 return $img;
1422}
1423
1424
1425{
1426 my $got_expr;
1427 sub transform2 {
1428 my ($opts, @imgs) = @_;
1429
1430 if (!$got_expr) {
1431 # this is fairly big, delay loading it
1432 eval "use Imager::Expr";
1433 die $@ if $@;
1434 ++$got_expr;
1435 }
1436
1437 $opts->{variables} = [ qw(x y) ];
1438 my ($width, $height) = @{$opts}{qw(width height)};
1439 if (@imgs) {
1440 $width ||= $imgs[0]->getwidth();
1441 $height ||= $imgs[0]->getheight();
1442 my $img_num = 1;
1443 for my $img (@imgs) {
1444 $opts->{constants}{"w$img_num"} = $img->getwidth();
1445 $opts->{constants}{"h$img_num"} = $img->getheight();
1446 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
1447 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
1448 ++$img_num;
1449 }
1450 }
1451 if ($width) {
1452 $opts->{constants}{w} = $width;
1453 $opts->{constants}{cx} = $width/2;
1454 }
1455 else {
1456 $Imager::ERRSTR = "No width supplied";
1457 return;
1458 }
1459 if ($height) {
1460 $opts->{constants}{h} = $height;
1461 $opts->{constants}{cy} = $height/2;
1462 }
1463 else {
1464 $Imager::ERRSTR = "No height supplied";
1465 return;
1466 }
1467 my $code = Imager::Expr->new($opts);
1468 if (!$code) {
1469 $Imager::ERRSTR = Imager::Expr::error();
1470 return;
1471 }
1472
1473 my $img = Imager->new();
1474 $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
1475 $code->nregs(), $code->cregs(),
1476 [ map { $_->{IMG} } @imgs ]);
1477 if (!defined $img->{IMG}) {
1478 $Imager::ERRSTR = "transform2 failed";
1479 return;
1480 }
1481
1482 return $img;
1483 }
1484}
1485
02d1d628
AMH
1486sub rubthrough {
1487 my $self=shift;
1488 my %opts=(tx=>0,ty=>0,@_);
1489
1490 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1491 unless ($opts{src} && $opts{src}->{IMG}) { $self->{ERRSTR}='empty input image for source'; return undef; }
1492
faa9b3e7
TC
1493 unless (i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx},$opts{ty})) {
1494 $self->{ERRSTR} = $self->_error_as_msg();
1495 return undef;
1496 }
02d1d628
AMH
1497 return $self;
1498}
1499
1500
142c26ff
AMH
1501sub flip {
1502 my $self = shift;
1503 my %opts = @_;
9191e525 1504 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
142c26ff
AMH
1505 my $dir;
1506 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
1507 $dir = $xlate{$opts{'dir'}};
1508 return $self if i_flipxy($self->{IMG}, $dir);
1509 return ();
1510}
1511
faa9b3e7
TC
1512sub rotate {
1513 my $self = shift;
1514 my %opts = @_;
1515 if (defined $opts{right}) {
1516 my $degrees = $opts{right};
1517 if ($degrees < 0) {
1518 $degrees += 360 * int(((-$degrees)+360)/360);
1519 }
1520 $degrees = $degrees % 360;
1521 if ($degrees == 0) {
1522 return $self->copy();
1523 }
1524 elsif ($degrees == 90 || $degrees == 180 || $degrees == 270) {
1525 my $result = Imager->new();
1526 if ($result->{IMG} = i_rotate90($self->{IMG}, $degrees)) {
1527 return $result;
1528 }
1529 else {
1530 $self->{ERRSTR} = $self->_error_as_msg();
1531 return undef;
1532 }
1533 }
1534 else {
1535 $self->{ERRSTR} = "Parameter 'right' must be a multiple of 90 degrees";
1536 return undef;
1537 }
1538 }
1539 elsif (defined $opts{radians} || defined $opts{degrees}) {
1540 my $amount = $opts{radians} || $opts{degrees} * 3.1415926535 / 180;
1541
1542 my $result = Imager->new;
1543 if ($result->{IMG} = i_rotate_exact($self->{IMG}, $amount)) {
1544 return $result;
1545 }
1546 else {
1547 $self->{ERRSTR} = $self->_error_as_msg();
1548 return undef;
1549 }
1550 }
1551 else {
1552 $self->{ERRSTR} = "Only the 'right' parameter is available";
1553 return undef;
1554 }
1555}
1556
1557sub matrix_transform {
1558 my $self = shift;
1559 my %opts = @_;
1560
1561 if ($opts{matrix}) {
1562 my $xsize = $opts{xsize} || $self->getwidth;
1563 my $ysize = $opts{ysize} || $self->getheight;
142c26ff 1564
faa9b3e7
TC
1565 my $result = Imager->new;
1566 $result->{IMG} = i_matrix_transform($self->{IMG}, $xsize, $ysize,
1567 $opts{matrix})
1568 or return undef;
1569
1570 return $result;
1571 }
1572 else {
1573 $self->{ERRSTR} = "matrix parameter required";
1574 return undef;
1575 }
1576}
1577
1578# blame Leolo :)
1579*yatf = \&matrix_transform;
02d1d628
AMH
1580
1581# These two are supported for legacy code only
1582
1583sub i_color_new {
faa9b3e7 1584 return Imager::Color->new(@_);
02d1d628
AMH
1585}
1586
1587sub i_color_set {
faa9b3e7 1588 return Imager::Color::set(@_);
02d1d628
AMH
1589}
1590
02d1d628 1591# Draws a box between the specified corner points.
02d1d628
AMH
1592sub box {
1593 my $self=shift;
1594 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1595 my $dflcl=i_color_new(255,255,255,255);
1596 my %opts=(color=>$dflcl,xmin=>0,ymin=>0,xmax=>$self->getwidth()-1,ymax=>$self->getheight()-1,@_);
1597
1598 if (exists $opts{'box'}) {
1599 $opts{'xmin'} = min($opts{'box'}->[0],$opts{'box'}->[2]);
1600 $opts{'xmax'} = max($opts{'box'}->[0],$opts{'box'}->[2]);
1601 $opts{'ymin'} = min($opts{'box'}->[1],$opts{'box'}->[3]);
1602 $opts{'ymax'} = max($opts{'box'}->[1],$opts{'box'}->[3]);
1603 }
1604
1605 if ($opts{filled}) { i_box_filled($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1606 else { i_box($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1607 return $self;
1608}
1609
1610# Draws an arc - this routine SUCKS and is buggy - it sometimes doesn't work when the arc is a convex polygon
1611
1612sub arc {
1613 my $self=shift;
1614 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1615 my $dflcl=i_color_new(255,255,255,255);
1616 my %opts=(color=>$dflcl,
1617 'r'=>min($self->getwidth(),$self->getheight())/3,
1618 'x'=>$self->getwidth()/2,
1619 'y'=>$self->getheight()/2,
1620 'd1'=>0, 'd2'=>361, @_);
1621 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},$opts{'d2'},$opts{'color'});
1622 return $self;
1623}
1624
1625# Draws a line from one point to (but not including) the destination point
1626
1627sub line {
1628 my $self=shift;
1629 my $dflcl=i_color_new(0,0,0,0);
1630 my %opts=(color=>$dflcl,@_);
1631 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1632
1633 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
1634 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
1635
1636 if ($opts{antialias}) {
1637 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1638 } else {
1639 i_draw($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1640 }
1641 return $self;
1642}
1643
1644# Draws a line between an ordered set of points - It more or less just transforms this
1645# into a list of lines.
1646
1647sub polyline {
1648 my $self=shift;
1649 my ($pt,$ls,@points);
1650 my $dflcl=i_color_new(0,0,0,0);
1651 my %opts=(color=>$dflcl,@_);
1652
1653 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1654
1655 if (exists($opts{points})) { @points=@{$opts{points}}; }
1656 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
1657 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
1658 }
1659
1660# print Dumper(\@points);
1661
1662 if ($opts{antialias}) {
1663 for $pt(@points) {
1664 if (defined($ls)) { i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1665 $ls=$pt;
1666 }
1667 } else {
1668 for $pt(@points) {
1669 if (defined($ls)) { i_draw($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1670 $ls=$pt;
1671 }
1672 }
1673 return $self;
1674}
1675
1676# this the multipoint bezier curve
1677# this is here more for testing that actual usage since
1678# this is not a good algorithm. Usually the curve would be
1679# broken into smaller segments and each done individually.
1680
1681sub polybezier {
1682 my $self=shift;
1683 my ($pt,$ls,@points);
1684 my $dflcl=i_color_new(0,0,0,0);
1685 my %opts=(color=>$dflcl,@_);
1686
1687 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1688
1689 if (exists $opts{points}) {
1690 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
1691 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
1692 }
1693
1694 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
1695 $self->{ERRSTR}='Missing or invalid points.';
1696 return;
1697 }
1698
1699 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$opts{'color'});
1700 return $self;
1701}
1702
f5991c03
TC
1703# make an identity matrix of the given size
1704sub _identity {
1705 my ($size) = @_;
1706
1707 my $matrix = [ map { [ (0) x $size ] } 1..$size ];
1708 for my $c (0 .. ($size-1)) {
1709 $matrix->[$c][$c] = 1;
1710 }
1711 return $matrix;
1712}
1713
1714# general function to convert an image
1715sub convert {
1716 my ($self, %opts) = @_;
1717 my $matrix;
1718
1719 # the user can either specify a matrix or preset
1720 # the matrix overrides the preset
1721 if (!exists($opts{matrix})) {
1722 unless (exists($opts{preset})) {
1723 $self->{ERRSTR} = "convert() needs a matrix or preset";
1724 return;
1725 }
1726 else {
1727 if ($opts{preset} eq 'gray' || $opts{preset} eq 'grey') {
1728 # convert to greyscale, keeping the alpha channel if any
1729 if ($self->getchannels == 3) {
1730 $matrix = [ [ 0.222, 0.707, 0.071 ] ];
1731 }
1732 elsif ($self->getchannels == 4) {
1733 # preserve the alpha channel
1734 $matrix = [ [ 0.222, 0.707, 0.071, 0 ],
1735 [ 0, 0, 0, 1 ] ];
1736 }
1737 else {
1738 # an identity
1739 $matrix = _identity($self->getchannels);
1740 }
1741 }
1742 elsif ($opts{preset} eq 'noalpha') {
1743 # strip the alpha channel
1744 if ($self->getchannels == 2 or $self->getchannels == 4) {
1745 $matrix = _identity($self->getchannels);
1746 pop(@$matrix); # lose the alpha entry
1747 }
1748 else {
1749 $matrix = _identity($self->getchannels);
1750 }
1751 }
1752 elsif ($opts{preset} eq 'red' || $opts{preset} eq 'channel0') {
1753 # extract channel 0
1754 $matrix = [ [ 1 ] ];
1755 }
1756 elsif ($opts{preset} eq 'green' || $opts{preset} eq 'channel1') {
1757 $matrix = [ [ 0, 1 ] ];
1758 }
1759 elsif ($opts{preset} eq 'blue' || $opts{preset} eq 'channel2') {
1760 $matrix = [ [ 0, 0, 1 ] ];
1761 }
1762 elsif ($opts{preset} eq 'alpha') {
1763 if ($self->getchannels == 2 or $self->getchannels == 4) {
1764 $matrix = [ [ (0) x ($self->getchannels-1), 1 ] ];
1765 }
1766 else {
1767 # the alpha is just 1 <shrug>
1768 $matrix = [ [ (0) x $self->getchannels, 1 ] ];
1769 }
1770 }
1771 elsif ($opts{preset} eq 'rgb') {
1772 if ($self->getchannels == 1) {
1773 $matrix = [ [ 1 ], [ 1 ], [ 1 ] ];
1774 }
1775 elsif ($self->getchannels == 2) {
1776 # preserve the alpha channel
1777 $matrix = [ [ 1, 0 ], [ 1, 0 ], [ 1, 0 ], [ 0, 1 ] ];
1778 }
1779 else {
1780 $matrix = _identity($self->getchannels);
1781 }
1782 }
1783 elsif ($opts{preset} eq 'addalpha') {
1784 if ($self->getchannels == 1) {
1785 $matrix = _identity(2);
1786 }
1787 elsif ($self->getchannels == 3) {
1788 $matrix = _identity(4);
1789 }
1790 else {
1791 $matrix = _identity($self->getchannels);
1792 }
1793 }
1794 else {
1795 $self->{ERRSTR} = "Unknown convert preset $opts{preset}";
1796 return undef;
1797 }
1798 }
1799 }
1800 else {
1801 $matrix = $opts{matrix};
1802 }
1803
1804 my $new = Imager->new();
1805 $new->{IMG} = i_img_new();
1806 unless (i_convert($new->{IMG}, $self->{IMG}, $matrix)) {
1807 # most likely a bad matrix
1808 $self->{ERRSTR} = _error_as_msg();
1809 return undef;
1810 }
1811 return $new;
1812}
40eba1ea
AMH
1813
1814
40eba1ea 1815# general function to map an image through lookup tables
9495ee93 1816
40eba1ea
AMH
1817sub map {
1818 my ($self, %opts) = @_;
9495ee93 1819 my @chlist = qw( red green blue alpha );
40eba1ea
AMH
1820
1821 if (!exists($opts{'maps'})) {
1822 # make maps from channel maps
1823 my $chnum;
1824 for $chnum (0..$#chlist) {
9495ee93
AMH
1825 if (exists $opts{$chlist[$chnum]}) {
1826 $opts{'maps'}[$chnum] = $opts{$chlist[$chnum]};
1827 } elsif (exists $opts{'all'}) {
1828 $opts{'maps'}[$chnum] = $opts{'all'};
1829 }
40eba1ea
AMH
1830 }
1831 }
1832 if ($opts{'maps'} and $self->{IMG}) {
1833 i_map($self->{IMG}, $opts{'maps'} );
1834 }
1835 return $self;
1836}
1837
02d1d628
AMH
1838# destructive border - image is shrunk by one pixel all around
1839
1840sub border {
1841 my ($self,%opts)=@_;
1842 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
1843 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
1844}
1845
1846
1847# Get the width of an image
1848
1849sub getwidth {
1850 my $self = shift;
1851 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1852 return (i_img_info($self->{IMG}))[0];
1853}
1854
1855# Get the height of an image
1856
1857sub getheight {
1858 my $self = shift;
1859 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1860 return (i_img_info($self->{IMG}))[1];
1861}
1862
1863# Get number of channels in an image
1864
1865sub getchannels {
1866 my $self = shift;
1867 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1868 return i_img_getchannels($self->{IMG});
1869}
1870
1871# Get channel mask
1872
1873sub getmask {
1874 my $self = shift;
1875 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1876 return i_img_getmask($self->{IMG});
1877}
1878
1879# Set channel mask
1880
1881sub setmask {
1882 my $self = shift;
1883 my %opts = @_;
1884 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1885 i_img_setmask( $self->{IMG} , $opts{mask} );
1886}
1887
1888# Get number of colors in an image
1889
1890sub getcolorcount {
1891 my $self=shift;
1892 my %opts=(maxcolors=>2**30,@_);
1893 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
1894 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
1895 return ($rc==-1? undef : $rc);
1896}
1897
1898# draw string to an image
1899
1900sub string {
1901 my $self = shift;
1902 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1903
1904 my %input=('x'=>0, 'y'=>0, @_);
1905 $input{string}||=$input{text};
1906
1907 unless(exists $input{string}) {
1908 $self->{ERRSTR}="missing required parameter 'string'";
1909 return;
1910 }
1911
1912 unless($input{font}) {
1913 $self->{ERRSTR}="missing required parameter 'font'";
1914 return;
1915 }
1916
faa9b3e7
TC
1917 unless ($input{font}->draw(image=>$self, %input)) {
1918 $self->{ERRSTR} = $self->_error_as_msg();
1919 return;
1920 }
02d1d628
AMH
1921
1922 return $self;
1923}
1924
02d1d628
AMH
1925# Shortcuts that can be exported
1926
1927sub newcolor { Imager::Color->new(@_); }
1928sub newfont { Imager::Font->new(@_); }
1929
1930*NC=*newcolour=*newcolor;
1931*NF=*newfont;
1932
1933*open=\&read;
1934*circle=\&arc;
1935
1936
1937#### Utility routines
1938
faa9b3e7
TC
1939sub errstr {
1940 ref $_[0] ? $_[0]->{ERRSTR} : $ERRSTR
1941}
02d1d628
AMH
1942
1943# Default guess for the type of an image from extension
1944
1945sub def_guess_type {
1946 my $name=lc(shift);
1947 my $ext;
1948 $ext=($name =~ m/\.([^\.]+)$/)[0];
1949 return 'tiff' if ($ext =~ m/^tiff?$/);
1950 return 'jpeg' if ($ext =~ m/^jpe?g$/);
1951 return 'pnm' if ($ext =~ m/^p[pgb]m$/);
1952 return 'png' if ($ext eq "png");
705fd961 1953 return 'bmp' if ($ext eq "bmp" || $ext eq "dib");
02d1d628
AMH
1954 return 'gif' if ($ext eq "gif");
1955 return ();
1956}
1957
1958# get the minimum of a list
1959
1960sub min {
1961 my $mx=shift;
1962 for(@_) { if ($_<$mx) { $mx=$_; }}
1963 return $mx;
1964}
1965
1966# get the maximum of a list
1967
1968sub max {
1969 my $mx=shift;
1970 for(@_) { if ($_>$mx) { $mx=$_; }}
1971 return $mx;
1972}
1973
1974# string stuff for iptc headers
1975
1976sub clean {
1977 my($str)=$_[0];
1978 $str = substr($str,3);
1979 $str =~ s/[\n\r]//g;
1980 $str =~ s/\s+/ /g;
1981 $str =~ s/^\s//;
1982 $str =~ s/\s$//;
1983 return $str;
1984}
1985
1986# A little hack to parse iptc headers.
1987
1988sub parseiptc {
1989 my $self=shift;
1990 my(@sar,$item,@ar);
1991 my($caption,$photogr,$headln,$credit);
1992
1993 my $str=$self->{IPTCRAW};
1994
1995 #print $str;
1996
1997 @ar=split(/8BIM/,$str);
1998
1999 my $i=0;
2000 foreach (@ar) {
2001 if (/^\004\004/) {
2002 @sar=split(/\034\002/);
2003 foreach $item (@sar) {
2004 if ($item =~ m/^x/) {
2005 $caption=&clean($item);
2006 $i++;
2007 }
2008 if ($item =~ m/^P/) {
2009 $photogr=&clean($item);
2010 $i++;
2011 }
2012 if ($item =~ m/^i/) {
2013 $headln=&clean($item);
2014 $i++;
2015 }
2016 if ($item =~ m/^n/) {
2017 $credit=&clean($item);
2018 $i++;
2019 }
2020 }
2021 }
2022 }
2023 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
2024}
2025
02d1d628
AMH
2026# Autoload methods go after =cut, and are processed by the autosplit program.
2027
20281;
2029__END__
2030# Below is the stub of documentation for your module. You better edit it!
2031
2032=head1 NAME
2033
2034Imager - Perl extension for Generating 24 bit Images
2035
2036=head1 SYNOPSIS
2037
2038 use Imager qw(init);
2039
2040 init();
2041 $img = Imager->new();
2042 $img->open(file=>'image.ppm',type=>'pnm')
2043 || print "failed: ",$img->{ERRSTR},"\n";
2044 $scaled=$img->scale(xpixels=>400,ypixels=>400);
2045 $scaled->write(file=>'sc_image.ppm',type=>'pnm')
2046 || print "failed: ",$scaled->{ERRSTR},"\n";
2047
2048=head1 DESCRIPTION
2049
2050Imager is a module for creating and altering images - It is not meant
2051as a replacement or a competitor to ImageMagick or GD. Both are
2052excellent packages and well supported.
2053
2054=head2 API
2055
2056Almost all functions take the parameters in the hash fashion.
2057Example:
2058
2059 $img->open(file=>'lena.png',type=>'png');
2060
2061or just:
2062
2063 $img->open(file=>'lena.png');
2064
2065=head2 Basic concept
2066
2067An Image object is created with C<$img = Imager-E<gt>new()> Should
2068this fail for some reason an explanation can be found in
2069C<$Imager::ERRSTR> usually error messages are stored in
2070C<$img-E<gt>{ERRSTR}>, but since no object is created this is the only
2071way to give back errors. C<$Imager::ERRSTR> is also used to report
2072all errors not directly associated with an image object. Examples:
2073
2074 $img=Imager->new(); # This is an empty image (size is 0 by 0)
2075 $img->open(file=>'lena.png',type=>'png'); # initializes from file
2076
2077or if you want to create an empty image:
2078
2079 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
2080
2081This example creates a completely black image of width 400 and
2082height 300 and 4 channels.
2083
2084If you have an existing image, use img_set() to change it's dimensions
2085- this will destroy any existing image data:
2086
2087 $img->img_set(xsize=>500, ysize=>500, channels=>4);
2088
faa9b3e7
TC
2089To create paletted images, set the 'type' parameter to 'paletted':
2090
2091 $img = Imager->new(xsize=>200, ysize=>200, channels=>3, type=>'paletted');
2092
2093which creates an image with a maxiumum of 256 colors, which you can
2094change by supplying the C<maxcolors> parameter.
2095
2096You can create a new paletted image from an existing image using the
2097to_paletted() method:
2098
2099 $palimg = $img->to_paletted(\%opts)
2100
2101where %opts contains the options specified under L<Quantization options>.
2102
2103You can convert a paletted image (or any image) to an 8-bit/channel
2104RGB image with:
2105
2106 $rgbimg = $img->to_rgb8;
2107
2108Warning: if you draw on a paletted image with colors that aren't in
2109the palette, the image will be internally converted to a normal image.
2110
2111For improved color precision you can use the bits parameter to specify
211216 bites per channel:
2113
2114 $img = Imager->new(xsize=>200, ysize=>200, channels=>3, bits=>16);
2115
2116Note that as of this writing all functions should work on 16-bit
2117images, but at only 8-bit/channel precision.
2118
2119Currently only 8 and 16/bit per channel image types are available,
2120this may change later.
2121
02d1d628
AMH
2122Color objects are created by calling the Imager::Color->new()
2123method:
2124
2125 $color = Imager::Color->new($red, $green, $blue);
2126 $color = Imager::Color->new($red, $green, $blue, $alpha);
2127 $color = Imager::Color->new("#C0C0FF"); # html color specification
2128
2129This object can then be passed to functions that require a color parameter.
2130
2131Coordinates in Imager have the origin in the upper left corner. The
2132horizontal coordinate increases to the right and the vertical
2133downwards.
2134
2135=head2 Reading and writing images
2136
2137C<$img-E<gt>read()> generally takes two parameters, 'file' and 'type'.
2138If the type of the file can be determined from the suffix of the file
2139it can be omitted. Format dependant parameters are: For images of
2140type 'raw' two extra parameters are needed 'xsize' and 'ysize', if the
2141'channel' parameter is omitted for type 'raw' it is assumed to be 3.
2142gif and png images might have a palette are converted to truecolor bit
2143when read. Alpha channel is preserved for png images irregardless of
2144them being in RGB or gray colorspace. Similarly grayscale jpegs are
2145one channel images after reading them. For jpeg images the iptc
2146header information (stored in the APP13 header) is avaliable to some
2147degree. You can get the raw header with C<$img-E<gt>{IPTCRAW}>, but
2148you can also retrieve the most basic information with
d2dfdcc9
TC
2149C<%hsh=$img-E<gt>parseiptc()> as always patches are welcome. pnm has no
2150extra options. Examples:
02d1d628
AMH
2151
2152 $img = Imager->new();
2153 $img->read(file=>"cover.jpg") or die $img->errstr; # gets type from name
2154
2155 $img = Imager->new();
2156 { local(*FH,$/); open(FH,"file.gif") or die $!; $a=<FH>; }
2157 $img->read(data=>$a,type=>'gif') or die $img->errstr;
2158
2159The second example shows how to read an image from a scalar, this is
2160usefull if your data originates from somewhere else than a filesystem
2161such as a database over a DBI connection.
2162
d2dfdcc9
TC
2163When writing to a tiff image file you can also specify the 'class'
2164parameter, which can currently take a single value, "fax". If class
2165is set to fax then a tiff image which should be suitable for faxing
2166will be written. For the best results start with a grayscale image.
4c2d6970
TC
2167By default the image is written at fine resolution you can override
2168this by setting the "fax_fine" parameter to 0.
d2dfdcc9 2169
a59ffd27
TC
2170If you are reading from a gif image file, you can supply a 'colors'
2171parameter which must be a reference to a scalar. The referenced
2172scalar will receive an array reference which contains the colors, each
e72d3bb1 2173represented as an Imager::Color object.
a59ffd27 2174
04516c2b
TC
2175If you already have an open file handle, for example a socket or a
2176pipe, you can specify the 'fd' parameter instead of supplying a
2177filename. Please be aware that you need to use fileno() to retrieve
2178the file descriptor for the file:
2179
2180 $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr;
2181
2182For writing using the 'fd' option you will probably want to set $| for
2183that descriptor, since the writes to the file descriptor bypass Perl's
2184(or the C libraries) buffering. Setting $| should avoid out of order
2185output.
2186
02d1d628
AMH
2187*Note that load() is now an alias for read but will be removed later*
2188
2189C<$img-E<gt>write> has the same interface as C<read()>. The earlier
2190comments on C<read()> for autodetecting filetypes apply. For jpegs
2191quality can be adjusted via the 'jpegquality' parameter (0-100). The
2192number of colorplanes in gifs are set with 'gifplanes' and should be
2193between 1 (2 color) and 8 (256 colors). It is also possible to choose
2194between two quantizing methods with the parameter 'gifquant'. If set
2195to mc it uses the mediancut algorithm from either giflibrary. If set
2196to lm it uses a local means algorithm. It is then possible to give
2197some extra settings. lmdither is the dither deviation amount in pixels
2198(manhattan distance). lmfixed can be an array ref who holds an array
2199of Imager::Color objects. Note that the local means algorithm needs
2200much more cpu time but also gives considerable better results than the
2201median cut algorithm.
2202
2203Currently just for gif files, you can specify various options for the
2204conversion from Imager's internal RGB format to the target's indexed
2205file format. If you set the gifquant option to 'gen', you can use the
2206options specified under L<Quantization options>.
2207
2208To see what Imager is compiled to support the following code snippet
2209is sufficient:
2210
2211 use Imager;
2212 print "@{[keys %Imager::formats]}";
2213
7febf116
TC
2214When reading raw images you need to supply the width and height of the
2215image in the xsize and ysize options:
2216
2217 $img->read(file=>'foo.raw', xsize=>100, ysize=>100)
2218 or die "Cannot read raw image\n";
2219
2220If your input file has more channels than you want, or (as is common),
2221junk in the fourth channel, you can use the datachannels and
2222storechannels options to control the number of channels in your input
2223file and the resulting channels in your image. For example, if your
2224input image uses 32-bits per pixel with red, green, blue and junk
2225values for each pixel you could do:
2226
2227 $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4,
2228 storechannels=>3)
2229 or die "Cannot read raw image\n";
2230
d04ee244
TC
2231Normally the raw image is expected to have the value for channel 1
2232immediately following channel 0 and channel 2 immediately following
2233channel 1 for each pixel. If your input image has all the channel 0
2234values for the first line of the image, followed by all the channel 1
2235values for the first line and so on, you can use the interleave option:
2236
2237 $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1)
2238 or die "Cannot read raw image\n";
2239
02d1d628
AMH
2240=head2 Multi-image files
2241
2242Currently just for gif files, you can create files that contain more
2243than one image.
2244
2245To do this:
2246
2247 Imager->write_multi(\%opts, @images)
2248
b9029e27 2249Where %opts describes 4 possible types of outputs:
02d1d628 2250
b9029e27
AMH
2251=over 5
2252
2253=item type
2254
2255This is C<gif> for gif animations.
02d1d628
AMH
2256
2257=item callback
2258
2259A code reference which is called with a single parameter, the data to
2260be written. You can also specify $opts{maxbuffer} which is the
2261maximum amount of data buffered. Note that there can be larger writes
2262than this if the file library writes larger blocks. A smaller value
2263maybe useful for writing to a socket for incremental display.
2264
2265=item fd
2266
2267The file descriptor to save the images to.
2268
2269=item file
2270
2271The name of the file to write to.
2272
2273%opts may also include the keys from L<Gif options> and L<Quantization
2274options>.
2275
2276=back
2277
f5991c03
TC
2278You must also specify the file format using the 'type' option.
2279
02d1d628
AMH
2280The current aim is to support other multiple image formats in the
2281future, such as TIFF, and to support reading multiple images from a
2282single file.
2283
2284A simple example:
2285
2286 my @images;
2287 # ... code to put images in @images
2288 Imager->write_multi({type=>'gif',
2289 file=>'anim.gif',
f5991c03 2290 gif_delays=>[ (10) x @images ] },
02d1d628
AMH
2291 @images)
2292 or die "Oh dear!";
2293
faa9b3e7
TC
2294You can read multi-image files (currently only GIF files) using the
2295read_multi() method:
2296
2297 my @imgs = Imager->read_multi(file=>'foo.gif')
2298 or die "Cannot read images: ",Imager->errstr;
2299
2300The possible parameters for read_multi() are:
2301
2302=over
2303
2304=item file
2305
2306The name of the file to read in.
2307
2308=item fh
2309
2310A filehandle to read in. This can be the name of a filehandle, but it
2311will need the package name, no attempt is currently made to adjust
2312this to the caller's package.
2313
2314=item fd
2315
2316The numeric file descriptor of an open file (or socket).
2317
2318=item callback
2319
2320A function to be called to read in data, eg. reading a blob from a
2321database incrementally.
2322
2323=item data
2324
2325The data of the input file in memory.
2326
2327=item type
2328
2329The type of file. If the file is parameter is given and provides
2330enough information to guess the type, then this parameter is optional.
2331
2332=back
2333
2334Note: you cannot use the callback or data parameter with giflib
2335versions before 4.0.
2336
2337When reading from a GIF file with read_multi() the images are returned
2338as paletted images.
2339
02d1d628
AMH
2340=head2 Gif options
2341
2342These options can be specified when calling write_multi() for gif
2343files, when writing a single image with the gifquant option set to
2344'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
2345
2346Note that some viewers will ignore some of these options
2347(gif_user_input in particular).
2348
2349=over 4
2350
2351=item gif_each_palette
2352
2353Each image in the gif file has it's own palette if this is non-zero.
2354All but the first image has a local colour table (the first uses the
2355global colour table.
2356
2357=item interlace
2358
2359The images are written interlaced if this is non-zero.
2360
2361=item gif_delays
2362
2363A reference to an array containing the delays between images, in 1/100
2364seconds.
2365
ed88b092
TC
2366If you want the same delay for every frame you can simply set this to
2367the delay in 1/100 seconds.
2368
02d1d628
AMH
2369=item gif_user_input
2370
2371A reference to an array contains user input flags. If the given flag
2372is non-zero the image viewer should wait for input before displaying
2373the next image.
2374
2375=item gif_disposal
2376
2377A reference to an array of image disposal methods. These define what
2378should be done to the image before displaying the next one. These are
2379integers, where 0 means unspecified, 1 means the image should be left
2380in place, 2 means restore to background colour and 3 means restore to
2381the previous value.
2382
2383=item gif_tran_color
2384
2385A reference to an Imager::Color object, which is the colour to use for
ae235ea6
TC
2386the palette entry used to represent transparency in the palette. You
2387need to set the transp option (see L<Quantization options>) for this
2388value to be used.
02d1d628
AMH
2389
2390=item gif_positions
2391
2392A reference to an array of references to arrays which represent screen
2393positions for each image.
2394
2395=item gif_loop_count
2396
2397If this is non-zero the Netscape loop extension block is generated,
2398which makes the animation of the images repeat.
2399
2400This is currently unimplemented due to some limitations in giflib.
2401
2402=back
2403
2404=head2 Quantization options
2405
2406These options can be specified when calling write_multi() for gif
2407files, when writing a single image with the gifquant option set to
2408'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
2409
2410=over 4
2411
2412=item colors
2413
2414A arrayref of colors that are fixed. Note that some color generators
2415will ignore this.
2416
2417=item transp
2418
2419The type of transparency processing to perform for images with an
2420alpha channel where the output format does not have a proper alpha
2421channel (eg. gif). This can be any of:
2422
2423=over 4
2424
2425=item none
2426
2427No transparency processing is done. (default)
2428
2429=item threshold
2430
2431Pixels more transparent that tr_threshold are rendered as transparent.
2432
2433=item errdiff
2434
2435An error diffusion dither is done on the alpha channel. Note that
2436this is independent of the translation performed on the colour
2437channels, so some combinations may cause undesired artifacts.
2438
2439=item ordered
2440
2441The ordered dither specified by tr_orddith is performed on the alpha
2442channel.
2443
2444=back
2445
ae235ea6
TC
2446This will only be used if the image has an alpha channel, and if there
2447is space in the palette for a transparency colour.
2448
02d1d628
AMH
2449=item tr_threshold
2450
2451The highest alpha value at which a pixel will be made transparent when
2452transp is 'threshold'. (0-255, default 127)
2453
2454=item tr_errdiff
2455
2456The type of error diffusion to perform on the alpha channel when
2457transp is 'errdiff'. This can be any defined error diffusion type
2458except for custom (see errdiff below).
2459
626cabcc 2460=item tr_orddith
02d1d628
AMH
2461
2462The type of ordered dither to perform on the alpha channel when transp
626cabcc 2463is 'ordered'. Possible values are:
02d1d628
AMH
2464
2465=over 4
2466
2467=item random
2468
529ef1f3 2469A semi-random map is used. The map is the same each time.
02d1d628
AMH
2470
2471=item dot8
2472
24738x8 dot dither.
2474
2475=item dot4
2476
24774x4 dot dither
2478
2479=item hline
2480
2481horizontal line dither.
2482
2483=item vline
2484
2485vertical line dither.
2486
2487=item "/line"
2488
2489=item slashline
2490
2491diagonal line dither
2492
2493=item '\line'
2494
2495=item backline
2496
2497diagonal line dither
2498
529ef1f3
TC
2499=item tiny
2500
2501dot matrix dither (currently the default). This is probably the best
2502for displays (like web pages).
2503
02d1d628
AMH
2504=item custom
2505
2506A custom dither matrix is used - see tr_map
2507
2508=back
2509
2510=item tr_map
2511
2512When tr_orddith is custom this defines an 8 x 8 matrix of integers
2513representing the transparency threshold for pixels corresponding to
2514each position. This should be a 64 element array where the first 8
2515entries correspond to the first row of the matrix. Values should be
2516betweern 0 and 255.
2517
2518=item make_colors
2519
2520Defines how the quantization engine will build the palette(s).
2521Currently this is ignored if 'translate' is 'giflib', but that may
2522change. Possible values are:
2523
2524=over 4
2525
2526=item none
2527
2528Only colors supplied in 'colors' are used.
2529
2530=item webmap
2531
2532The web color map is used (need url here.)
2533
2534=item addi
2535
2536The original code for generating the color map (Addi's code) is used.
2537
2538=back
2539
2540Other methods may be added in the future.
2541
2542=item colors
2543
2544A arrayref containing Imager::Color objects, which represents the
2545starting set of colors to use in translating the images. webmap will
2546ignore this. The final colors used are copied back into this array
2547(which is expanded if necessary.)
2548
2549=item max_colors
2550
2551The maximum number of colors to use in the image.
2552
2553=item translate
2554
2555The method used to translate the RGB values in the source image into
2556the colors selected by make_colors. Note that make_colors is ignored
2557whene translate is 'giflib'.
2558
2559Possible values are:
2560
2561=over 4
2562
2563=item giflib
2564
2565The giflib native quantization function is used.
2566
2567=item closest
2568
2569The closest color available is used.
2570
2571=item perturb
2572
2573The pixel color is modified by perturb, and the closest color is chosen.
2574
2575=item errdiff
2576
2577An error diffusion dither is performed.
2578
2579=back
2580
2581It's possible other transate values will be added.
2582
2583=item errdiff
2584
2585The type of error diffusion dither to perform. These values (except
2586for custom) can also be used in tr_errdif.
2587
2588=over 4
2589
2590=item floyd
2591
2592Floyd-Steinberg dither
2593
2594=item jarvis
2595
2596Jarvis, Judice and Ninke dither
2597
2598=item stucki
2599
2600Stucki dither
2601
2602=item custom
2603
2604Custom. If you use this you must also set errdiff_width,
2605errdiff_height and errdiff_map.
2606
2607=back
2608
2609=item errdiff_width
2610
2611=item errdiff_height
2612
2613=item errdiff_orig
2614
2615=item errdiff_map
2616
2617When translate is 'errdiff' and errdiff is 'custom' these define a
2618custom error diffusion map. errdiff_width and errdiff_height define
2619the size of the map in the arrayref in errdiff_map. errdiff_orig is
2620an integer which indicates the current pixel position in the top row
2621of the map.
2622
2623=item perturb
2624
2625When translate is 'perturb' this is the magnitude of the random bias
2626applied to each channel of the pixel before it is looked up in the
2627color table.
2628
2629=back
2630
2631=head2 Obtaining/setting attributes of images
2632
2633To get the size of an image in pixels the C<$img-E<gt>getwidth()> and
2634C<$img-E<gt>getheight()> are used.
2635
2636To get the number of channels in
2637an image C<$img-E<gt>getchannels()> is used. $img-E<gt>getmask() and
2638$img-E<gt>setmask() are used to get/set the channel mask of the image.
2639
2640 $mask=$img->getmask();
2641 $img->setmask(mask=>1+2); # modify red and green only
2642 $img->setmask(mask=>8); # modify alpha only
2643 $img->setmask(mask=>$mask); # restore previous mask
2644
2645The mask of an image describes which channels are updated when some
2646operation is performed on an image. Naturally it is not possible to
2647apply masks to operations like scaling that alter the dimensions of
2648images.
2649
2650It is possible to have Imager find the number of colors in an image
2651by using C<$img-E<gt>getcolorcount()>. It requires memory proportionally
2652to the number of colors in the image so it is possible to have it
2653stop sooner if you only need to know if there are more than a certain number
2654of colors in the image. If there are more colors than asked for
2655the function return undef. Examples:
2656
2657 if (!defined($img->getcolorcount(maxcolors=>512)) {
2658 print "Less than 512 colors in image\n";
2659 }
2660
faa9b3e7
TC
2661The bits() method retrieves the number of bits used to represent each
2662channel in a pixel, typically 8. The type() method returns either
2663'direct' for truecolor images or 'paletted' for paletted images. The
2664virtual() method returns non-zero if the image contains no actual
2665pixels, for example masked images.
2666
2667=head2 Paletted Images
2668
2669In general you can work with paletted images in the same way as RGB
2670images, except that if you attempt to draw to a paletted image with a
2671color that is not in the image's palette, the image will be converted
2672to an RGB image. This means that drawing on a paletted image with
2673anti-aliasing enabled will almost certainly convert the image to RGB.
2674
2675You can add colors to a paletted image with the addcolors() method:
2676
2677 my @colors = ( Imager::Color->new(255, 0, 0),
2678 Imager::Color->new(0, 255, 0) );
2679 my $index = $img->addcolors(colors=>\@colors);
2680
2681The return value is the index of the first color added, or undef if
2682adding the colors would overflow the palette.
2683
2684Once you have colors in the palette you can overwrite them with the
2685setcolors() method:
2686
2687 $img->setcolors(start=>$start, colors=>\@colors);
2688
2689Returns true on success.
2690
2691To retrieve existing colors from the palette use the getcolors() method:
2692
2693 # get the whole palette
2694 my @colors = $img->getcolors();
2695 # get a single color
2696 my $color = $img->getcolors(start=>$index);
2697 # get a range of colors
2698 my @colors = $img->getcolors(start=>$index, count=>$count);
2699
2700To quickly find a color in the palette use findcolor():
2701
2702 my $index = $img->findcolor(color=>$color);
2703
2704which returns undef on failure, or the index of the color.
2705
2706You can get the current palette size with $img->colorcount, and the
2707maximum size of the palette with $img->maxcolors.
2708
02d1d628
AMH
2709=head2 Drawing Methods
2710
2711IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS
02d1d628
AMH
2712DOCUMENTATION OF THIS SECTION OUT OF SYNC
2713
2714It is possible to draw with graphics primitives onto images. Such
2715primitives include boxes, arcs, circles and lines. A reference
2716oriented list follows.
2717
2718Box:
2719 $img->box(color=>$blue,xmin=>10,ymin=>30,xmax=>200,ymax=>300,filled=>1);
2720
2721The above example calls the C<box> method for the image and the box
2722covers the pixels with in the rectangle specified. If C<filled> is
2723ommited it is drawn as an outline. If any of the edges of the box are
2724ommited it will snap to the outer edge of the image in that direction.
2725Also if a color is omitted a color with (255,255,255,255) is used
2726instead.
2727
2728Arc:
2729 $img->arc(color=>$red, r=20, x=>200, y=>100, d1=>10, d2=>20 );
2730
2731This creates a filled red arc with a 'center' at (200, 100) and spans
273210 degrees and the slice has a radius of 20. SEE section on BUGS.
2733
2734Circle:
2735 $img->circle(color=>$green, r=50, x=>200, y=>100);
2736
2737This creates a green circle with its center at (200, 100) and has a
2738radius of 20.
2739
2740Line:
2741 $img->line(color=>$green, x1=10, x2=>100,
2742 y1=>20, y2=>50, antialias=>1 );
2743
2744That draws an antialiased line from (10,100) to (20,50).
2745
2746Polyline:
2747 $img->polyline(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2]],color=>$red);
2748 $img->polyline(x=>[$x0,$x1,$x2], y=>[$y0,$y1,$y2], antialias=>1);
2749
2750Polyline is used to draw multilple lines between a series of points.
2751The point set can either be specified as an arrayref to an array of
2752array references (where each such array represents a point). The
2753other way is to specify two array references.
2754
2755=head2 Text rendering
2756
2757Text rendering is described in the Imager::Font manpage.
2758
2759=head2 Image resizing
2760
2761To scale an image so porportions are maintained use the
2762C<$img-E<gt>scale()> method. if you give either a xpixels or ypixels
2763parameter they will determine the width or height respectively. If
2764both are given the one resulting in a larger image is used. example:
2765C<$img> is 700 pixels wide and 500 pixels tall.
2766
2767 $img->scale(xpixels=>400); # 400x285
2768 $img->scale(ypixels=>400); # 560x400
2769
2770 $img->scale(xpixels=>400,ypixels=>400); # 560x400
2771 $img->scale(xpixels=>400,ypixels=>400,type=>min); # 400x285
2772
2773 $img->scale(scalefactor=>0.25); 175x125 $img->scale(); # 350x250
2774
2775if you want to create low quality previews of images you can pass
2776C<qtype=E<gt>'preview'> to scale and it will use nearest neighbor
2777sampling instead of filtering. It is much faster but also generates
2778worse looking images - especially if the original has a lot of sharp
2779variations and the scaled image is by more than 3-5 times smaller than
2780the original.
2781
2782If you need to scale images per axis it is best to do it simply by
2783calling scaleX and scaleY. You can pass either 'scalefactor' or
2784'pixels' to both functions.
2785
2786Another way to resize an image size is to crop it. The parameters
2787to crop are the edges of the area that you want in the returned image.
2788If a parameter is omited a default is used instead.
2789
2790 $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100);
2791 $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
2792 $newimg = $img->crop(left=>50, right=>100); # top
2793
2794You can also specify width and height parameters which will produce a
2795new image cropped from the center of the input image, with the given
2796width and height.
2797
2798 $newimg = $img->crop(width=>50, height=>50);
2799
2800The width and height parameters take precedence over the left/right
2801and top/bottom parameters respectively.
2802
2803=head2 Copying images
2804
2805To create a copy of an image use the C<copy()> method. This is usefull
2806if you want to keep an original after doing something that changes the image
2807inplace like writing text.
2808
2809 $img=$orig->copy();
2810
2811To copy an image to onto another image use the C<paste()> method.
2812
2813 $dest->paste(left=>40,top=>20,img=>$logo);
2814
2815That copies the entire C<$logo> image onto the C<$dest> image so that the
2816upper left corner of the C<$logo> image is at (40,20).
2817
142c26ff
AMH
2818
2819=head2 Flipping images
2820
2821An inplace horizontal or vertical flip is possible by calling the
9191e525
AMH
2822C<flip()> method. If the original is to be preserved it's possible to
2823make a copy first. The only parameter it takes is the C<dir>
2824parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
142c26ff 2825
9191e525
AMH
2826 $img->flip(dir=>"h"); # horizontal flip
2827 $img->flip(dir=>"vh"); # vertical and horizontal flip
2828 $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
142c26ff 2829
faa9b3e7
TC
2830=head2 Rotating images
2831
2832Use the rotate() method to rotate an image.
2833
2834To rotate by an exact amount in degrees or radians, use the 'degrees'
2835or 'radians' parameter:
2836
2837 my $rot20 = $img->rotate(degrees=>20);
2838 my $rotpi4 = $img->rotate(radians=>3.14159265/4);
2839
2840To rotate in steps of 90 degrees, use the 'right' parameter:
2841
2842 my $rotated = $img->rotate(right=>270);
2843
2844Rotations are clockwise for positive values.
2845
9191e525 2846=head2 Blending Images
142c26ff 2847
9191e525 2848To put an image or a part of an image directly
142c26ff
AMH
2849into another it is best to call the C<paste()> method on the image you
2850want to add to.
02d1d628
AMH
2851
2852 $img->paste(img=>$srcimage,left=>30,top=>50);
2853
2854That will take paste C<$srcimage> into C<$img> with the upper
2855left corner at (30,50). If no values are given for C<left>
2856or C<top> they will default to 0.
2857
2858A more complicated way of blending images is where one image is
2859put 'over' the other with a certain amount of opaqueness. The
2860method that does this is rubthrough.
2861
2862 $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
2863
faa9b3e7
TC
2864That will take the image C<$srcimage> and overlay it with the upper
2865left corner at (30,50). You can rub 2 or 4 channel images onto a 3
2866channel image, or a 2 channel image onto a 1 channel image. The last
2867channel is used as an alpha channel.
02d1d628
AMH
2868
2869
2870=head2 Filters
2871
2872A special image method is the filter method. An example is:
2873
2874 $img->filter(type=>'autolevels');
2875
2876This will call the autolevels filter. Here is a list of the filters
2877that are always avaliable in Imager. This list can be obtained by
2878running the C<filterlist.perl> script that comes with the module
2879source.
2880
2881 Filter Arguments
02d1d628 2882 autolevels lsat(0.1) usat(0.1) skew(0)
d08b8f85 2883 bumpmap bump elevation(0) lightx lighty st(2)
02d1d628 2884 contrast intensity
faa9b3e7 2885 conv coef
6607600c
TC
2886 fountain xa ya xb yb ftype(linear) repeat(none) combine(0)
2887 super_sample(none) ssample_param(4) segments(see below)
faa9b3e7 2888 gaussian stddev
02d1d628 2889 gradgen xo yo colors dist
faa9b3e7 2890 hardinvert
6607600c 2891 mosaic size(20)
faa9b3e7 2892 noise amount(3) subtype(0)
d08b8f85 2893 postlevels levels(10)
faa9b3e7
TC
2894 radnoise xo(100) yo(100) ascale(17.0) rscale(0.02)
2895 turbnoise xo(0.0) yo(0.0) scale(10.0)
d08b8f85 2896 watermark wmark pixdiff(10) tx(0) ty(0)
02d1d628
AMH
2897
2898The default values are in parenthesis. All parameters must have some
2899value but if a parameter has a default value it may be omitted when
2900calling the filter function.
2901
faa9b3e7
TC
2902The filters are:
2903
2904=over
2905
2906=item autolevels
2907
2908scales the value of each channel so that the values in the image will
2909cover the whole possible range for the channel. I<lsat> and I<usat>
2910truncate the range by the specified fraction at the top and bottom of
2911the range respectivly..
2912
d08b8f85
TC
2913=item bumpmap
2914
2915uses the channel I<elevation> image I<bump> as a bumpmap on your
2916image, with the light at (I<lightx>, I<lightty>), with a shadow length
2917of I<st>.
2918
faa9b3e7
TC
2919=item contrast
2920
2921scales each channel by I<intensity>. Values of I<intensity> < 1.0
2922will reduce the contrast.
2923
2924=item conv
2925
2926performs 2 1-dimensional convolutions on the image using the values
2927from I<coef>. I<coef> should be have an odd length.
2928
6607600c
TC
2929=item fountain
2930
2931renders a fountain fill, similar to the gradient tool in most paint
2932software. The default fill is a linear fill from opaque black to
2933opaque white. The points A(xa, ya) and B(xb, yb) control the way the
2934fill is performed, depending on the ftype parameter:
2935
2936=over
2937
2938=item linear
2939
2940the fill ramps from A through to B.
2941
2942=item bilinear
2943
2944the fill ramps in both directions from A, where AB defines the length
2945of the gradient.
2946
2947=item radial
2948
2949A is the center of a circle, and B is a point on it's circumference.
2950The fill ramps from the center out to the circumference.
2951
2952=item radial_square
2953
2954A is the center of a square and B is the center of one of it's sides.
2955This can be used to rotate the square. The fill ramps out to the
2956edges of the square.
2957
2958=item revolution
2959
2960A is the centre of a circle and B is a point on it's circumference. B
2961marks the 0 and 360 point on the circle, with the fill ramping
2962clockwise.
2963
2964=item conical
2965
2966A is the center of a circle and B is a point on it's circumference. B
2967marks the 0 and point on the circle, with the fill ramping in both
2968directions to meet opposite.
2969
2970=back
2971
2972The I<repeat> option controls how the fill is repeated for some
2973I<ftype>s after it leaves the AB range:
2974
2975=over
2976
2977=item none
2978
2979no repeats, points outside of each range are treated as if they were
2980on the extreme end of that range.
2981
2982=item sawtooth
2983
2984the fill simply repeats in the positive direction
2985
2986=item triangle
2987
2988the fill repeats in reverse and then forward and so on, in the
2989positive direction
2990
2991=item saw_both
2992
2993the fill repeats in both the positive and negative directions (only
2994meaningful for a linear fill).
2995
2996=item tri_both
2997
2998as for triangle, but in the negative direction too (only meaningful
2999for a linear fill).
3000
3001=back
3002
3003By default the fill simply overwrites the whole image (unless you have
3004parts of the range 0 through 1 that aren't covered by a segment), if
3005any segments of your fill have any transparency, you can set the
3006I<combine> option to 1 to have the fill combined with the existing pixels.
3007
3008If your fill has sharp edges, for example between steps if you use
3009repeat set to 'triangle', you may see some aliased or ragged edges.
3010You can enable super-sampling which will take extra samples within the
3011pixel in an attempt anti-alias the fill.
3012
3013The possible values for the super_sample option are:
3014
3015=over
3016
3017=item none
3018
3019no super-sampling is done
3020
3021=item grid
3022
3023a square grid of points are sampled. The number of points sampled is
3024the square of ceil(0.5 + sqrt(ssample_param)).
3025
3026=item random
3027
3028a random set of points within the pixel are sampled. This looks
3029pretty bad for low ssample_param values.
3030
3031=item circle
3032
3033the points on the radius of a circle within the pixel are sampled.
3034This seems to produce the best results, but is fairly slow (for now).
3035
3036=back
3037
3038You can control the level of sampling by setting the ssample_param
3039option. This is roughly the number of points sampled, but depends on
3040the type of sampling.
3041
3042The segments option is an arrayref of segments. You really should use
3043the Imager::Fountain class to build your fountain fill. Each segment
3044is an array ref containing:
3045
3046=over
3047
3048=item start
3049
3050a floating point number between 0 and 1, the start of the range of fill parameters covered by this segment.
3051
3052=item middle
3053
3054a floating point number between start and end which can be used to
3055push the color range towards one end of the segment.
3056
3057=item end
3058
3059a floating point number between 0 and 1, the end of the range of fill
3060parameters covered by this segment. This should be greater than
3061start.
3062
3063=item c0
3064
3065=item c1
3066
3067The colors at each end of the segment. These can be either
3068Imager::Color or Imager::Color::Float objects.
3069
3070=item segment type
3071
3072The type of segment, this controls the way the fill parameter varies
3073over the segment. 0 for linear, 1 for curved (unimplemented), 2 for
3074sine, 3 for sphere increasing, 4 for sphere decreasing.
3075
3076=item color type
3077
3078The way the color varies within the segment, 0 for simple RGB, 1 for
3079hue increasing and 2 for hue decreasing.
3080
3081=back
3082
3083Don't forgot to use Imager::Fountain instead of building your own.
3084Really. It even loads GIMP gradient files.
3085
faa9b3e7
TC
3086=item gaussian
3087
3088performs a gaussian blur of the image, using I<stddev> as the standard
3089deviation of the curve used to combine pixels, larger values give
3090bigger blurs. For a definition of Gaussian Blur, see:
3091
3092 http://www.maths.abdn.ac.uk/~igc/tch/mx4002/notes/node99.html
3093
3094=item gradgen
3095
3096renders a gradient, with the given I<colors> at the corresponding
3097points (x,y) in I<xo> and I<yo>. You can specify the way distance is
3098measured for color blendeing by setting I<dist> to 0 for Euclidean, 1
3099for Euclidean squared, and 2 for Manhattan distance.
3100
3101=item hardinvert
3102
3103inverts the image, black to white, white to black. All channels are
3104inverted, including the alpha channel if any.
3105
6607600c
TC
3106=item mosaic
3107
3108produces averaged tiles of the given I<size>.
3109
faa9b3e7
TC
3110=item noise
3111
3112adds noise of the given I<amount> to the image. If I<subtype> is
3113zero, the noise is even to each channel, otherwise noise is added to
3114each channel independently.
3115
3116=item radnoise
3117
3118renders radiant Perlin turbulent noise. The centre of the noise is at
3119(I<xo>, I<yo>), I<ascale> controls the angular scale of the noise ,
3120and I<rscale> the radial scale, higher numbers give more detail.
3121
d08b8f85
TC
3122=item postlevels
3123
3124alters the image to have only I<levels> distinct level in each
3125channel.
3126
faa9b3e7
TC
3127=item turbnoise
3128
3129renders Perlin turbulent noise. (I<xo>, I<yo>) controls the origin of
3130the noise, and I<scale> the scale of the noise, with lower numbers
3131giving more detail.
3132
d08b8f85
TC
3133=item watermark
3134
3135applies I<wmark> as a watermark on the image with strength I<pixdiff>,
3136with an origin at (I<tx>, I<ty>)
3137
faa9b3e7
TC
3138=back
3139
d08b8f85 3140A demonstration of most of the filters can be found at:
faa9b3e7
TC
3141
3142 http://www.develop-help.com/imager/filters.html
3143
3144(This is a slow link.)
02d1d628 3145
f5991c03
TC
3146=head2 Color transformations
3147
3148You can use the convert method to transform the color space of an
3149image using a matrix. For ease of use some presets are provided.
3150
3151The convert method can be used to:
3152
3153=over 4
3154
3155=item *
3156
3157convert an RGB or RGBA image to grayscale.
3158
3159=item *
3160
3161convert a grayscale image to RGB.
3162
3163=item *
3164
3165extract a single channel from an image.
3166
3167=item *
3168
3169set a given channel to a particular value (or from another channel)
3170
3171=back
3172
3173The currently defined presets are:
3174
3175=over
3176
3177=item gray
3178
3179=item grey
3180
3181converts an RGBA image into a grayscale image with alpha channel, or
3182an RGB image into a grayscale image without an alpha channel.
3183
3184This weights the RGB channels at 22.2%, 70.7% and 7.1% respectively.
3185
3186=item noalpha
3187
3188removes the alpha channel from a 2 or 4 channel image. An identity
3189for other images.
3190
3191=item red
3192
3193=item channel0
3194
3195extracts the first channel of the image into a single channel image
3196
3197=item green
3198
3199=item channel1
3200
3201extracts the second channel of the image into a single channel image
3202
3203=item blue
3204
3205=item channel2
3206
3207extracts the third channel of the image into a single channel image
3208
3209=item alpha
3210
3211extracts the alpha channel of the image into a single channel image.
3212
3213If the image has 1 or 3 channels (assumed to be grayscale of RGB) then
3214the resulting image will be all white.
3215
3216=item rgb
3217
3218converts a grayscale image to RGB, preserving the alpha channel if any
3219
3220=item addalpha
3221
3222adds an alpha channel to a grayscale or RGB image. Preserves an
3223existing alpha channel for a 2 or 4 channel image.
3224
3225=back
3226
3227For example, to convert an RGB image into a greyscale image:
3228
3229 $new = $img->convert(preset=>'grey'); # or gray
3230
3231or to convert a grayscale image to an RGB image:
3232
3233 $new = $img->convert(preset=>'rgb');
3234
3235The presets aren't necessary simple constants in the code, some are
3236generated based on the number of channels in the input image.
3237
3238If you want to perform some other colour transformation, you can use
3239the 'matrix' parameter.
3240
3241For each output pixel the following matrix multiplication is done:
3242
3243 channel[0] [ [ $c00, $c01, ... ] inchannel[0]
3244 [ ... ] = ... x [ ... ]
3245 channel[n-1] [ $cn0, ..., $cnn ] ] inchannel[max]
3246 1
3247
3248So if you want to swap the red and green channels on a 3 channel image:
3249
3250 $new = $img->convert(matrix=>[ [ 0, 1, 0 ],
3251 [ 1, 0, 0 ],
3252 [ 0, 0, 1 ] ]);
3253
3254or to convert a 3 channel image to greyscale using equal weightings:
3255
3256 $new = $img->convert(matrix=>[ [ 0.333, 0.333, 0.334 ] ])
3257
9495ee93
AMH
3258=head2 Color Mappings
3259
3260You can use the map method to map the values of each channel of an
3261image independently using a list of lookup tables. It's important to
3262realize that the modification is made inplace. The function simply
3263returns the input image again or undef on failure.
3264
3265Each channel is mapped independently through a lookup table with 256
3266entries. The elements in the table should not be less than 0 and not
3267greater than 255. If they are out of the 0..255 range they are
3268clamped to the range. If a table does not contain 256 entries it is
3269silently ignored.
3270
3271Single channels can mapped by specifying their name and the mapping
3272table. The channel names are C<red>, C<green>, C<blue>, C<alpha>.
3273
3274 @map = map { int( $_/2 } 0..255;
3275 $img->map( red=>\@map );
3276
3277It is also possible to specify a single map that is applied to all
3278channels, alpha channel included. For example this applies a gamma
3279correction with a gamma of 1.4 to the input image.
3280
3281 $gamma = 1.4;
3282 @map = map { int( 0.5 + 255*($_/255)**$gamma ) } 0..255;
3283 $img->map(all=> \@map);
3284
3285The C<all> map is used as a default channel, if no other map is
3286specified for a channel then the C<all> map is used instead. If we
3287had not wanted to apply gamma to the alpha channel we would have used:
3288
3289 $img->map(all=> \@map, alpha=>[]);
3290
3291Since C<[]> contains fewer than 256 element the gamma channel is
3292unaffected.
3293
3294It is also possible to simply specify an array of maps that are
3295applied to the images in the rgba order. For example to apply
3296maps to the C<red> and C<blue> channels one would use:
3297
3298 $img->map(maps=>[\@redmap, [], \@bluemap]);
3299
3300
3301
02d1d628
AMH
3302=head2 Transformations
3303
3304Another special image method is transform. It can be used to generate
3305warps and rotations and such features. It can be given the operations
3306in postfix notation or the module Affix::Infix2Postfix can be used.
3307Look in the test case t/t55trans.t for an example.
3308
3309transform() needs expressions (or opcodes) that determine the source
3310pixel for each target pixel. Source expressions are infix expressions
3311using any of the +, -, *, / or ** binary operators, the - unary
3312operator, ( and ) for grouping and the sin() and cos() functions. The
3313target pixel is input as the variables x and y.
3314
3315You specify the x and y expressions as xexpr and yexpr respectively.
3316You can also specify opcodes directly, but that's magic deep enough
3317that you can look at the source code.
3318
3319You can still use the transform() function, but the transform2()
3320function is just as fast and is more likely to be enhanced and
3321maintained.
3322
3323Later versions of Imager also support a transform2() class method
3324which allows you perform a more general set of operations, rather than
3325just specifying a spatial transformation as with the transform()
3326method, you can also perform colour transformations, image synthesis
3327and image combinations.
3328
3329transform2() takes an reference to an options hash, and a list of
3330images to operate one (this list may be empty):
3331
3332 my %opts;
3333 my @imgs;
3334 ...
3335 my $img = Imager::transform2(\%opts, @imgs)
3336 or die "transform2 failed: $Imager::ERRSTR";
3337
3338The options hash may define a transformation function, and optionally:
3339
3340=over 4
3341
3342=item *
3343
3344width - the width of the image in pixels. If this isn't supplied the
3345width of the first input image is used. If there are no input images
3346an error occurs.
3347
3348=item *
3349
3350height - the height of the image in pixels. If this isn't supplied
3351the height of the first input image is used. If there are no input
3352images an error occurs.
3353
3354=item *
3355
3356constants - a reference to hash of constants to define for the
3357expression engine. Some extra constants are defined by Imager
3358
3359=back
3360
3361The tranformation function is specified using either the expr or
3362rpnexpr member of the options.
3363
3364=over 4
3365
3366=item Infix expressions
3367
3368You can supply infix expressions to transform 2 with the expr keyword.
3369
3370$opts{expr} = 'return getp1(w-x, h-y)'
3371
3372The 'expression' supplied follows this general grammar:
3373
3374 ( identifier '=' expr ';' )* 'return' expr
3375
3376This allows you to simplify your expressions using variables.
3377
3378A more complex example might be:
3379
3380$opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)'
3381
3382Currently to use infix expressions you must have the Parse::RecDescent
3383module installed (available from CPAN). There is also what might be a
3384significant delay the first time you run the infix expression parser
3385due to the compilation of the expression grammar.
3386
3387=item Postfix expressions
3388
3389You can supply postfix or reverse-polish notation expressions to
3390transform2() through the rpnexpr keyword.
3391
3392The parser for rpnexpr emulates a stack machine, so operators will
3393expect to see their parameters on top of the stack. A stack machine
3394isn't actually used during the image transformation itself.
3395
3396You can store the value at the top of the stack in a variable called
3397foo using !foo and retrieve that value again using @foo. The !foo
3398notation will pop the value from the stack.
3399
3400An example equivalent to the infix expression above:
3401
3402 $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp'
3403
3404=back
3405
3406transform2() has a fairly rich range of operators.
3407
3408=over 4
3409
3410=item +, *, -, /, %, **
3411
3412multiplication, addition, subtraction, division, remainder and
3413exponentiation. Multiplication, addition and subtraction can be used
3414on colour values too - though you need to be careful - adding 2 white
3415values together and multiplying by 0.5 will give you grey, not white.
3416
3417Division by zero (or a small number) just results in a large number.
3418Modulo zero (or a small number) results in zero.
3419
3420=item sin(N), cos(N), atan2(y,x)
3421
3422Some basic trig functions. They work in radians, so you can't just
3423use the hue values.
3424
3425=item distance(x1, y1, x2, y2)
3426
3427Find the distance between two points. This is handy (along with
3428atan2()) for producing circular effects.
3429
3430=item sqrt(n)
3431
3432Find the square root. I haven't had much use for this since adding
3433the distance() function.
3434
3435=item abs(n)
3436
3437Find the absolute value.
3438
3439=item getp1(x,y), getp2(x,y), getp3(x, y)
3440
3441Get the pixel at position (x,y) from the first, second or third image
3442respectively. I may add a getpn() function at some point, but this
3443prevents static checking of the instructions against the number of
3444images actually passed in.
3445
3446=item value(c), hue(c), sat(c), hsv(h,s,v)
3447
3448Separates a colour value into it's value (brightness), hue (colour)
3449and saturation elements. Use hsv() to put them back together (after
3450suitable manipulation).
3451
3452=item red(c), green(c), blue(c), rgb(r,g,b)
3453
3454Separates a colour value into it's red, green and blue colours. Use
3455rgb(r,g,b) to put it back together.
3456
3457=item int(n)
3458
3459Convert a value to an integer. Uses a C int cast, so it may break on
3460large values.
3461
3462=item if(cond,ntrue,nfalse), if(cond,ctrue,cfalse)
3463
3464A simple (and inefficient) if function.
3465
3466=item <=,<,==,>=,>,!=
3467
3468Relational operators (typically used with if()). Since we're working
3469with floating point values the equalities are 'near equalities' - an
3470epsilon value is used.
3471
3472=item &&, ||, not(n)
3473
3474Basic logical operators.
3475
3476=back
3477
3478A few examples:
3479
3480=over 4
3481
3482=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp'
3483
9495ee93
AMH
3484tiles a smaller version of the input image over itself where the
3485colour has a saturation over 0.7.
02d1d628
AMH
3486
3487=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd'
3488
3489tiles the input image over itself so that at the top of the image the
3490full-size image is at full strength and at the bottom the tiling is
3491most visible.
3492
3493=item rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp'
3494
3495replace pixels that are white or almost white with a palish blue
3496
3497=item rpnexpr=>'x 35 % 10 * y 45 % 8 * getp1 !pat x y getp1 !pix @pix sat 0.2 lt @pix value 0.9 gt and @pix @pat @pix value 2 / 0.5 + pmult ifp'
3498
3499Tiles the input image overitself where the image isn't white or almost
3500white.
3501
3502=item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a2 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
3503
3504Produces a spiral.
3505
3506=item rpnexpr=>'x y 160 180 distance !d y 180 - x 160 - atan2 !a @d 10 / @a + 3.1416 2 * % !a2 @a 180 * 3.1416 / 1 @a2 sin 1 + 2 / hsv'
3507
3508A spiral built on top of a colour wheel.
3509
3510=back
3511
3512For details on expression parsing see L<Imager::Expr>. For details on
3513the virtual machine used to transform the images, see
3514L<Imager::regmach.pod>.
3515
faa9b3e7
TC
3516=head2 Matrix Transformations
3517
3518Rather than having to write code in a little language, you can use a
3519matrix to perform transformations, using the matrix_transform()
3520method:
3521
3522 my $im2 = $im->matrix_transform(matrix=>[ -1, 0, $im->getwidth-1,
3523 0, 1, 0,
3524 0, 0, 1 ]);
3525
3526By default the output image will be the same size as the input image,
3527but you can supply the xsize and ysize parameters to change the size.
3528
3529Rather than building matrices by hand you can use the Imager::Matrix2d
3530module to build the matrices. This class has methods to allow you to
3531scale, shear, rotate, translate and reflect, and you can combine these
3532with an overloaded multiplication operator.
3533
3534WARNING: the matrix you provide in the matrix operator transforms the
3535co-ordinates within the B<destination> image to the co-ordinates
3536within the I<source> image. This can be confusing.
3537
3538Since Imager has 3 different fairly general ways of transforming an
3539image spatially, this method also has a yatf() alias. Yet Another
3540Transformation Function.
3541
3542=head2 Masked Images
3543
3544Masked images let you control which pixels are modified in an
3545underlying image. Where the first channel is completely black in the
3546mask image, writes to the underlying image are ignored.
3547
3548For example, given a base image called $img:
3549
3550 my $mask = Imager->new(xsize=>$img->getwidth, ysize=>getheight,
3551 channels=>1);
3552 # ... draw something on the mask
3553 my $maskedimg = $img->masked(mask=>$mask);
3554
3555You can specifiy the region of the underlying image that is masked
3556using the left, top, right and bottom options.
3557
3558If you just want a subset of the image, without masking, just specify
3559the region without specifying a mask.
3560
02d1d628
AMH
3561=head2 Plugins
3562
3563It is possible to add filters to the module without recompiling the
3564module itself. This is done by using DSOs (Dynamic shared object)
3565avaliable on most systems. This way you can maintain our own filters
3566and not have to get me to add it, or worse patch every new version of
3567the Module. Modules can be loaded AND UNLOADED at runtime. This
3568means that you can have a server/daemon thingy that can do something
3569like:
3570
3571 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
3572 %hsh=(a=>35,b=>200,type=>lin_stretch);
3573 $img->filter(%hsh);
3574 unload_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
3575 $img->write(type=>'pnm',file=>'testout/t60.jpg')
3576 || die "error in write()\n";
3577
3578Someone decides that the filter is not working as it should -
3579dyntest.c modified and recompiled.
3580
3581 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
3582 $img->filter(%hsh);
3583
3584An example plugin comes with the module - Please send feedback to
3585addi@umich.edu if you test this.
3586
3587Note: This seems to test ok on the following systems:
3588Linux, Solaris, HPUX, OpenBSD, FreeBSD, TRU64/OSF1, AIX.
3589If you test this on other systems please let me know.
3590
faa9b3e7
TC
3591=head2 Tags
3592
3593Image tags contain meta-data about the image, ie. information not
3594stored as pixels of the image.
3595
3596At the perl level each tag has a name or code and a value, which is an
3597integer or an arbitrary string. An image can contain more than one
3598tag with the same name or code.
3599
3600You can retrieve tags from an image using the tags() method, you can
3601get all of the tags in an image, as a list of array references, with
3602the code or name of the tag followed by the value of the tag:
3603
3604 my @alltags = $img->tags;
3605
3606or you can get all tags that have a given name:
3607
3608 my @namedtags = $img->tags(name=>$name);
3609
3610or a given code:
3611
3612 my @tags = $img->tags(code=>$code);
3613
3614You can add tags using the addtag() method, either by name:
3615
3616 my $index = $img->addtag(name=>$name, value=>$value);
3617
3618or by code:
3619
3620 my $index = $img->addtag(code=>$code, value=>$value);
3621
3622You can remove tags with the deltag() method, either by index:
3623
3624 $img->deltag(index=>$index);
3625
3626or by name:
3627
3628 $img->deltag(name=>$name);
3629
3630or by code:
3631
3632 $img->deltag(code=>$code);
3633
3634In each case deltag() returns the number of tags deleted.
3635
3636When you read a GIF image using read_multi(), each image can include
3637the following tags:
3638
3639=over
3640
3641=item gif_left
3642
3643the offset of the image from the left of the "screen" ("Image Left
3644Position")
3645
3646=item gif_top
3647
3648the offset of the image from the top of the "screen" ("Image Top Position")
3649
3650=item gif_interlace
3651
3652non-zero if the image was interlaced ("Interlace Flag")
3653
3654=item gif_screen_width
3655
3656=item gif_screen_height
3657
3658the size of the logical screen ("Logical Screen Width",
3659"Logical Screen Height")
3660
3661=item gif_local_map
3662
3663Non-zero if this image had a local color map.
3664
3665=item gif_background
3666
3667The index in the global colormap of the logical screen's background
3668color. This is only set if the current image uses the global
3669colormap.
3670
3671=item gif_trans_index
3672
3673The index of the color in the colormap used for transparency. If the
3674image has a transparency then it is returned as a 4 channel image with
3675the alpha set to zero in this palette entry. ("Transparent Color Index")
3676
3677=item gif_delay
3678
3679The delay until the next frame is displayed, in 1/100 of a second.
3680("Delay Time").
3681
3682=item gif_user_input
3683
3684whether or not a user input is expected before continuing (view dependent)
3685("User Input Flag").
3686
3687=item gif_disposal
3688
3689how the next frame is displayed ("Disposal Method")
3690
3691=item gif_loop
3692
3693the number of loops from the Netscape Loop extension. This may be zero.
3694
3695=item gif_comment
3696
3697the first block of the first gif comment before each image.
3698
3699=back
3700
3701Where applicable, the ("name") is the name of that field from the GIF89
3702standard.
3703
705fd961 3704The following tags are set in a TIFF image when read, and can be set
faa9b3e7
TC
3705to control output:
3706
3707=over
3708
3709=item tiff_resolutionunit
3710
3711The value of the ResolutionUnit tag. This is ignored on writing if
3712the i_aspect_only tag is non-zero.
3713
3714=back
3715
705fd961
TC
3716The following tags are set when reading a Windows BMP file is read:
3717
3718=over
3719
3720=item bmp_compression
3721
3722The type of compression, if any.
3723
3724=item bmp_important_colors
3725
3726The number of important colors as defined by the writer of the image.
3727
3728=back
3729
faa9b3e7
TC
3730Some standard tags will be implemented as time goes by:
3731
3732=over
3733
3734=item i_xres
3735
3736=item i_yres
3737
3738The spatial resolution of the image in pixels per inch. If the image
3739format uses a different scale, eg. pixels per meter, then this value
3740is converted. A floating point number stored as a string.
3741
3742=item i_aspect_only
3743
3744If this is non-zero then the values in i_xres and i_yres are treated
3745as a ratio only. If the image format does not support aspect ratios
3746then this is scaled so the smaller value is 72dpi.
3747
3748=back
3749
02d1d628
AMH
3750=head1 BUGS
3751
3752box, arc, circle do not support antialiasing yet. arc, is only filled
3753as of yet. Some routines do not return $self where they should. This
3754affects code like this, C<$img-E<gt>box()-E<gt>arc()> where an object
3755is expected.
3756
3757When saving Gif images the program does NOT try to shave of extra
3758colors if it is possible. If you specify 128 colors and there are
3759only 2 colors used - it will have a 128 colortable anyway.
3760
3761=head1 AUTHOR
3762
9495ee93
AMH
3763Arnar M. Hrafnkelsson, addi@umich.edu, and recently lots of assistance
3764from Tony Cook. See the README for a complete list.
02d1d628 3765
9495ee93 3766=head1 SEE ALSO
02d1d628 3767
faa9b3e7
TC
3768perl(1), Imager::Color(3), Imager::Font(3), Imager::Matrix2d(3),
3769Affix::Infix2Postfix(3), Parse::RecDescent(3)
3770http://www.eecs.umich.edu/~addi/perl/Imager/
02d1d628
AMH
3771
3772=cut