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