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