Added type=>gif for write_multi docs.
[imager.git] / Imager.pm
CommitLineData
02d1d628
AMH
1package Imager;
2
3
4
5use strict;
6use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS %formats $DEBUG %filters %DSOs $ERRSTR $fontstate %OPCODES $I2P $FORMATGUESS);
7use IO::File;
8
9use Imager::Color;
10use Imager::Font;
11
12@EXPORT_OK = qw(
13 init
14 init_log
15 DSO_open
16 DSO_close
17 DSO_funclist
18 DSO_call
19
20 load_plugin
21 unload_plugin
22
23 i_list_formats
24 i_has_format
25
26 i_color_new
27 i_color_set
28 i_color_info
29
30 i_img_empty
31 i_img_empty_ch
32 i_img_exorcise
33 i_img_destroy
34
35 i_img_info
36
37 i_img_setmask
38 i_img_getmask
39
40 i_draw
41 i_line_aa
42 i_box
43 i_box_filled
44 i_arc
45
46 i_bezier_multi
47 i_poly_aa
48
49 i_copyto
50 i_rubthru
51 i_scaleaxis
52 i_scale_nn
53 i_haar
54 i_count_colors
55
56
57 i_gaussian
58 i_conv
59
60 i_img_diff
61
62 i_init_fonts
63 i_t1_new
64 i_t1_destroy
65 i_t1_set_aa
66 i_t1_cp
67 i_t1_text
68 i_t1_bbox
69
70
71 i_tt_set_aa
72 i_tt_cp
73 i_tt_text
74 i_tt_bbox
75
76 i_readjpeg
77 i_writejpeg
78
79 i_readjpeg_wiol
80 i_writejpeg_wiol
81
82 i_readtiff_wiol
83 i_writetiff_wiol
d2dfdcc9 84 i_writetiff_wiol_faxable
02d1d628
AMH
85
86 i_readpng
87 i_writepng
88
89 i_readgif
90 i_readgif_callback
91 i_writegif
92 i_writegifmc
93 i_writegif_gen
94 i_writegif_callback
95
96 i_readpnm_wiol
97 i_writeppm
98
99 i_readraw
100 i_writeraw
101
102 i_contrast
103 i_hardinvert
104 i_noise
105 i_bumpmap
106 i_postlevels
107 i_mosaic
108 i_watermark
109
110 malloc_state
111
112 list_formats
113
114 i_gifquant
115
116 newfont
117 newcolor
118 newcolour
119 NC
120 NF
121
122);
123
124
125
126@EXPORT=qw(
127 init_log
128 i_list_formats
129 i_has_format
130 malloc_state
131 i_color_new
132
133 i_img_empty
134 i_img_empty_ch
135 );
136
137%EXPORT_TAGS=
138 (handy => [qw(
139 newfont
140 newcolor
141 NF
142 NC
143 )],
144 all => [@EXPORT_OK],
145 default => [qw(
146 load_plugin
147 unload_plugin
148 )]);
149
150
151BEGIN {
152 require Exporter;
153 require DynaLoader;
154
155 $VERSION = '0.38pre9';
156 @ISA = qw(Exporter DynaLoader);
157 bootstrap Imager $VERSION;
158}
159
160BEGIN {
161 i_init_fonts(); # Initialize font engines
162 for(i_list_formats()) { $formats{$_}++; }
163
164 if ($formats{'t1'}) {
165 i_t1_set_aa(1);
166 }
167
168 if (!$formats{'t1'} and !$formats{'tt'}) {
169 $fontstate='no font support';
170 }
171
172 %OPCODES=(Add=>[0],Sub=>[1],Mult=>[2],Div=>[3],Parm=>[4],'sin'=>[5],'cos'=>[6],'x'=>[4,0],'y'=>[4,1]);
173
174 $DEBUG=0;
175
176 $filters{contrast}={
177 callseq => ['image','intensity'],
178 callsub => sub { my %hsh=@_; i_contrast($hsh{image},$hsh{intensity}); }
179 };
180
181 $filters{noise} ={
182 callseq => ['image', 'amount', 'subtype'],
183 defaults => { amount=>3,subtype=>0 },
184 callsub => sub { my %hsh=@_; i_noise($hsh{image},$hsh{amount},$hsh{subtype}); }
185 };
186
187 $filters{hardinvert} ={
188 callseq => ['image'],
189 defaults => { },
190 callsub => sub { my %hsh=@_; i_hardinvert($hsh{image}); }
191 };
192
193 $filters{autolevels} ={
194 callseq => ['image','lsat','usat','skew'],
195 defaults => { lsat=>0.1,usat=>0.1,skew=>0.0 },
196 callsub => sub { my %hsh=@_; i_autolevels($hsh{image},$hsh{lsat},$hsh{usat},$hsh{skew}); }
197 };
198
199 $filters{turbnoise} ={
200 callseq => ['image'],
201 defaults => { xo=>0.0,yo=>0.0,scale=>10.0 },
202 callsub => sub { my %hsh=@_; i_turbnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{scale}); }
203 };
204
205 $filters{radnoise} ={
206 callseq => ['image'],
207 defaults => { xo=>100,yo=>100,ascale=>17.0,rscale=>0.02 },
208 callsub => sub { my %hsh=@_; i_radnoise($hsh{image},$hsh{xo},$hsh{yo},$hsh{rscale},$hsh{ascale}); }
209 };
210
211 $filters{conv} ={
212 callseq => ['image', 'coef'],
213 defaults => { },
214 callsub => sub { my %hsh=@_; i_conv($hsh{image},$hsh{coef}); }
215 };
216
217 $filters{gradgen} ={
218 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
219 defaults => { },
220 callsub => sub { my %hsh=@_; i_gradgen($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
221 };
222
223 $filters{nearest_color} ={
224 callseq => ['image', 'xo', 'yo', 'colors', 'dist'],
225 defaults => { },
226 callsub => sub { my %hsh=@_; i_nearest_color($hsh{image}, $hsh{xo}, $hsh{yo}, $hsh{colors}, $hsh{dist}); }
227 };
228
229 $FORMATGUESS=\&def_guess_type;
230}
231
232#
233# Non methods
234#
235
236# initlize Imager
237# NOTE: this might be moved to an import override later on
238
239#sub import {
240# my $pack = shift;
241# (look through @_ for special tags, process, and remove them);
242# use Data::Dumper;
243# print Dumper($pack);
244# print Dumper(@_);
245#}
246
247sub init {
248 my %parms=(loglevel=>1,@_);
249 if ($parms{'log'}) {
250 init_log($parms{'log'},$parms{'loglevel'});
251 }
252
253# if ($parms{T1LIB_CONFIG}) { $ENV{T1LIB_CONFIG}=$parms{T1LIB_CONFIG}; }
254# if ( $ENV{T1LIB_CONFIG} and ( $fontstate eq 'missing conf' )) {
255# i_init_fonts();
256# $fontstate='ok';
257# }
258}
259
260END {
261 if ($DEBUG) {
262 print "shutdown code\n";
263 # for(keys %instances) { $instances{$_}->DESTROY(); }
264 malloc_state(); # how do decide if this should be used? -- store something from the import
265 print "Imager exiting\n";
266 }
267}
268
269# Load a filter plugin
270
271sub load_plugin {
272 my ($filename)=@_;
273 my $i;
274 my ($DSO_handle,$str)=DSO_open($filename);
275 if (!defined($DSO_handle)) { $Imager::ERRSTR="Couldn't load plugin '$filename'\n"; return undef; }
276 my %funcs=DSO_funclist($DSO_handle);
277 if ($DEBUG) { print "loading module $filename\n"; $i=0; for(keys %funcs) { printf(" %2d: %s\n",$i++,$_); } }
278 $i=0;
279 for(keys %funcs) { if ($filters{$_}) { $ERRSTR="filter '$_' already exists\n"; DSO_close($DSO_handle); return undef; } }
280
281 $DSOs{$filename}=[$DSO_handle,\%funcs];
282
283 for(keys %funcs) {
284 my $evstr="\$filters{'".$_."'}={".$funcs{$_}.'};';
285 $DEBUG && print "eval string:\n",$evstr,"\n";
286 eval $evstr;
287 print $@ if $@;
288 }
289 return 1;
290}
291
292# Unload a plugin
293
294sub unload_plugin {
295 my ($filename)=@_;
296
297 if (!$DSOs{$filename}) { $ERRSTR="plugin '$filename' not loaded."; return undef; }
298 my ($DSO_handle,$funcref)=@{$DSOs{$filename}};
299 for(keys %{$funcref}) {
300 delete $filters{$_};
301 $DEBUG && print "unloading: $_\n";
302 }
303 my $rc=DSO_close($DSO_handle);
304 if (!defined($rc)) { $ERRSTR="unable to unload plugin '$filename'."; return undef; }
305 return 1;
306}
307
64606cc7
TC
308# take the results of i_error() and make a message out of it
309sub _error_as_msg {
310 return join(": ", map $_->[0], i_errors());
311}
312
02d1d628
AMH
313
314#
315# Methods to be called on objects.
316#
317
318# Create a new Imager object takes very few parameters.
319# usually you call this method and then call open from
320# the resulting object
321
322sub new {
323 my $class = shift;
324 my $self ={};
325 my %hsh=@_;
326 bless $self,$class;
327 $self->{IMG}=undef; # Just to indicate what exists
328 $self->{ERRSTR}=undef; #
329 $self->{DEBUG}=$DEBUG;
330 $self->{DEBUG} && print "Initialized Imager\n";
331 if ($hsh{xsize} && $hsh{ysize}) { $self->img_set(%hsh); }
332 return $self;
333}
334
335
336# Copy an entire image with no changes
337# - if an image has magic the copy of it will not be magical
338
339sub copy {
340 my $self = shift;
341 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
342
343 my $newcopy=Imager->new();
344 $newcopy->{IMG}=i_img_new();
345 i_copy($newcopy->{IMG},$self->{IMG});
346 return $newcopy;
347}
348
349# Paste a region
350
351sub paste {
352 my $self = shift;
353 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
354 my %input=(left=>0, top=>0, @_);
355 unless($input{img}) {
356 $self->{ERRSTR}="no source image";
357 return;
358 }
359 $input{left}=0 if $input{left} <= 0;
360 $input{top}=0 if $input{top} <= 0;
361 my $src=$input{img};
362 my($r,$b)=i_img_info($src->{IMG});
363
364 i_copyto($self->{IMG}, $src->{IMG},
365 0,0, $r, $b, $input{left}, $input{top});
366 return $self; # What should go here??
367}
368
369# Crop an image - i.e. return a new image that is smaller
370
371sub crop {
372 my $self=shift;
373 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
374 my %hsh=(left=>0,right=>0,top=>0,bottom=>0,@_);
375
376 my ($w,$h,$l,$r,$b,$t)=($self->getwidth(),$self->getheight(),
377 @hsh{qw(left right bottom top)});
378 $l=0 if not defined $l;
379 $t=0 if not defined $t;
380 $r=$self->getwidth if not defined $r;
381 $b=$self->getheight if not defined $b;
382
383 ($l,$r)=($r,$l) if $l>$r;
384 ($t,$b)=($b,$t) if $t>$b;
385
386 if ($hsh{'width'}) {
387 $l=int(0.5+($w-$hsh{'width'})/2);
388 $r=$l+$hsh{'width'};
389 } else {
390 $hsh{'width'}=$r-$l;
391 }
392 if ($hsh{'height'}) {
393 $b=int(0.5+($h-$hsh{'height'})/2);
394 $t=$h+$hsh{'height'};
395 } else {
396 $hsh{'height'}=$b-$t;
397 }
398
399# print "l=$l, r=$r, h=$hsh{'width'}\n";
400# print "t=$t, b=$b, w=$hsh{'height'}\n";
401
402 my $dst=Imager->new(xsize=>$hsh{'width'},ysize=>$hsh{'height'},channels=>$self->getchannels());
403
404 i_copyto($dst->{IMG},$self->{IMG},$l,$t,$r,$b,0,0);
405 return $dst;
406}
407
408# Sets an image to a certain size and channel number
409# if there was previously data in the image it is discarded
410
411sub img_set {
412 my $self=shift;
413
414 my %hsh=(xsize=>100,ysize=>100,channels=>3,@_);
415
416 if (defined($self->{IMG})) {
417 i_img_destroy($self->{IMG});
418 undef($self->{IMG});
419 }
420
421 $self->{IMG}=Imager::ImgRaw::new($hsh{'xsize'},$hsh{'ysize'},$hsh{'channels'});
422}
423
424# Read an image from file
425
426sub read {
427 my $self = shift;
428 my %input=@_;
429 my ($fh, $fd, $IO);
430
431 if (defined($self->{IMG})) {
432 i_img_destroy($self->{IMG});
433 undef($self->{IMG});
434 }
435
436 if (!$input{fd} and !$input{file} and !$input{data}) { $self->{ERRSTR}='no file, fd or data parameter'; return undef; }
437 if ($input{file}) {
438 $fh = new IO::File($input{file},"r");
439 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
440 binmode($fh);
441 $fd = $fh->fileno();
442 }
443 if ($input{fd}) { $fd=$input{fd} };
444
445 # FIXME: Find the format here if not specified
446 # yes the code isn't here yet - next week maybe?
447
448 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
449 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
450
451 my %iolready=(jpeg=>1, tiff=>1, pnm=>1);
452
453 if ($iolready{$input{type}}) {
454 # Setup data source
455 $IO = io_new_fd($fd); # sort of simple for now eh?
456
457 if ( $input{type} eq 'jpeg' ) {
458 ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_wiol( $IO );
459 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read jpeg image'; return undef; }
460 $self->{DEBUG} && print "loading a jpeg file\n";
461 return $self;
462 }
463
464 if ( $input{type} eq 'tiff' ) {
465 $self->{IMG}=i_readtiff_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
466 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read tiff image'; return undef; }
467 $self->{DEBUG} && print "loading a tiff file\n";
468 return $self;
469 }
470
471 if ( $input{type} eq 'pnm' ) {
472 $self->{IMG}=i_readpnm_wiol( $IO, -1 ); # Fixme, check if that length parameter is ever needed
64606cc7 473 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read pnm image: '._error_as_msg(); return undef; }
02d1d628
AMH
474 $self->{DEBUG} && print "loading a pnm file\n";
475 return $self;
476 }
477
478 } else {
479
480 # Old code for reference while changing the new stuff
481
482
483 if (!$input{type} and $input{file}) { $input{type}=$FORMATGUESS->($input{file}); }
484 if (!$input{type}) { $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef; }
485
486 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
487
488 if ($input{file}) {
489 $fh = new IO::File($input{file},"r");
490 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
491 binmode($fh);
492 $fd = $fh->fileno();
493 }
494 if ($input{fd}) { $fd=$input{fd} };
495
496 if ( $input{type} eq 'gif' ) {
e72d3bb1 497 my $colors;
a59ffd27
TC
498 if ($input{colors} && !ref($input{colors})) {
499 # must be a reference to a scalar that accepts the colour map
500 $self->{ERRSTR} = "option 'colors' must be a scalar reference";
501 return undef;
502 }
503 if (exists $input{data}) {
504 if ($input{colors}) {
e72d3bb1 505 ($self->{IMG}, $colors) = i_readgif_scalar($input{data});
a59ffd27
TC
506 }
507 else {
508 $self->{IMG}=i_readgif_scalar($input{data});
509 }
510 }
511 else {
512 if ($input{colors}) {
e72d3bb1 513 ($self->{IMG}, $colors) = i_readgif( $fd );
a59ffd27
TC
514 }
515 else {
516 $self->{IMG} = i_readgif( $fd )
517 }
518 }
e72d3bb1
TC
519 if ($colors) {
520 # we may or may not change i_readgif to return blessed objects...
521 ${$input{colors}} = [ map { NC(@$_) } @$colors ];
522 }
a59ffd27
TC
523 if ( !defined($self->{IMG}) ) {
524 $self->{ERRSTR}= 'reading GIF:'._error_as_msg(); return undef;
525 }
02d1d628
AMH
526 $self->{DEBUG} && print "loading a gif file\n";
527 } elsif ( $input{type} eq 'jpeg' ) {
528 if (exists $input{data}) { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg_scalar($input{data}); }
529 else { ($self->{IMG},$self->{IPTCRAW})=i_readjpeg( $fd ); }
530 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read jpeg image'; return undef; }
531 $self->{DEBUG} && print "loading a jpeg file\n";
532 } elsif ( $input{type} eq 'png' ) {
533 if (exists $input{data}) { $self->{IMG}=i_readpng_scalar($input{data}); }
534 else { $self->{IMG}=i_readpng( $fd ); }
535 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read png image'; return undef; }
536 $self->{DEBUG} && print "loading a png file\n";
537 } elsif ( $input{type} eq 'raw' ) {
538 my %params=(datachannels=>3,storechannels=>3,interleave=>1);
539 for(keys(%input)) { $params{$_}=$input{$_}; }
540
541 if ( !($params{xsize} && $params{ysize}) ) { $self->{ERRSTR}='missing xsize or ysize parameter for raw'; return undef; }
542 $self->{IMG}=i_readraw( $fd, $params{xsize}, $params{ysize},
543 $params{datachannels}, $params{storechannels}, $params{interleave});
544 if ( !defined($self->{IMG}) ) { $self->{ERRSTR}='unable to read raw image'; return undef; }
545 $self->{DEBUG} && print "loading a raw file\n";
546 }
547 return $self;
548 }
549}
550
551
552# Write an image to file
553
554sub write {
555 my $self = shift;
556 my %input=(jpegquality=>75, gifquant=>'mc', lmdither=>6.0, lmfixed=>[], @_);
557 my ($fh, $rc, $fd, $IO);
558
559 my %iolready=( tiff=>1 ); # this will be SO MUCH BETTER once they are all in there
560
561 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
562
563 if (!$input{file} and !$input{'fd'} and !$input{'data'}) { $self->{ERRSTR}='file/fd/data parameter missing'; return undef; }
564 if (!$input{type}) { $input{type}=$FORMATGUESS->($input{file}); }
565 if (!$input{type}) { $self->{ERRSTR}='type parameter missing and not possible to guess from extension'; return undef; }
566
567 if (!$formats{$input{type}}) { $self->{ERRSTR}='format not supported'; return undef; }
568
569 if (exists $input{'fd'}) {
570 $fd=$input{'fd'};
571 } elsif (exists $input{'data'}) {
572 $IO = Imager::io_new_bufchain();
573 } else {
574 $fh = new IO::File($input{file},"w+");
575 if (!defined $fh) { $self->{ERRSTR}='Could not open file'; return undef; }
576 binmode($fh);
577 $fd = $fh->fileno();
578 }
579
580
581
582 if ($iolready{$input{type}}) {
583 if ($fd) {
584 $IO = io_new_fd($fd);
585 }
586
587 if ($input{type} eq 'tiff') {
d2dfdcc9
TC
588 if ($input{class} eq 'fax') {
589 if (!i_writetiff_wiol_faxable($self->{IMG}, $IO)) {
590 $self->{ERRSTR}='Could not write to buffer';
591 return undef;
592 }
593 }
594 else {
595 if (!i_writetiff_wiol($self->{IMG}, $IO)) {
596 $self->{ERRSTR}='Could not write to buffer';
597 return undef;
598 }
599 }
02d1d628
AMH
600 }
601
602 my $data = io_slurp($IO);
603 if (!$data) { $self->{ERRSTR}='Could not slurp from buffer'; return undef; }
604
605 ${$input{data}} = $data;
606 return $self;
607 } else {
608
609 if ( $input{type} eq 'gif' ) {
610 if (not $input{gifplanes}) {
611 my $gp;
612 my $count=i_count_colors($self->{IMG}, 256);
613 $gp=8 if $count == -1;
614 $gp=1 if not $gp and $count <= 2;
615 $gp=2 if not $gp and $count <= 4;
616 $gp=3 if not $gp and $count <= 8;
617 $gp=4 if not $gp and $count <= 16;
618 $gp=5 if not $gp and $count <= 32;
619 $gp=6 if not $gp and $count <= 64;
620 $gp=7 if not $gp and $count <= 128;
621 $input{gifplanes} = $gp || 8;
622 }
623
624 if ($input{gifplanes}>8) {
625 $input{gifplanes}=8;
626 }
627 if ($input{gifquant} eq 'gen' || $input{callback}) {
628
629
630 if ($input{gifquant} eq 'lm') {
631
632 $input{make_colors} = 'addi';
633 $input{translate} = 'perturb';
634 $input{perturb} = $input{lmdither};
635 } elsif ($input{gifquant} eq 'gen') {
636 # just pass options through
637 } else {
638 $input{make_colors} = 'webmap'; # ignored
639 $input{translate} = 'giflib';
640 }
641
642 if ($input{callback}) {
643 defined $input{maxbuffer} or $input{maxbuffer} = -1;
644 $rc = i_writegif_callback($input{callback}, $input{maxbuffer},
645 \%input, $self->{IMG});
646 } else {
647 $rc = i_writegif_gen($fd, \%input, $self->{IMG});
648 }
649
650
651
652 } elsif ($input{gifquant} eq 'lm') {
653 $rc=i_writegif($self->{IMG},$fd,$input{gifplanes},$input{lmdither},$input{lmfixed});
654 } else {
655 $rc=i_writegifmc($self->{IMG},$fd,$input{gifplanes});
656 }
657 if ( !defined($rc) ) {
3827fae0 658 $self->{ERRSTR} = "Writing GIF file: "._error_as_msg(); return undef;
02d1d628
AMH
659 }
660 $self->{DEBUG} && print "writing a gif file\n";
661
662 } elsif ( $input{type} eq 'jpeg' ) {
663 $rc=i_writejpeg($self->{IMG},$fd,$input{jpegquality});
664 if ( !defined($rc) ) {
665 $self->{ERRSTR}='unable to write jpeg image'; return undef;
666 }
667 $self->{DEBUG} && print "writing a jpeg file\n";
668 } elsif ( $input{type} eq 'png' ) {
669 $rc=i_writepng($self->{IMG},$fd);
670 if ( !defined($rc) ) {
671 $self->{ERRSTR}='unable to write png image'; return undef;
672 }
673 $self->{DEBUG} && print "writing a png file\n";
674 } elsif ( $input{type} eq 'pnm' ) {
675 $rc=i_writeppm($self->{IMG},$fd);
676 if ( !defined($rc) ) {
677 $self->{ERRSTR}='unable to write pnm image'; return undef;
678 }
679 $self->{DEBUG} && print "writing a pnm file\n";
680 } elsif ( $input{type} eq 'raw' ) {
681 $rc=i_writeraw($self->{IMG},$fd);
682 if ( !defined($rc) ) {
683 $self->{ERRSTR}='unable to write raw image'; return undef;
684 }
685 $self->{DEBUG} && print "writing a raw file\n";
686 } elsif ( $input{type} eq 'tiff' ) {
d2dfdcc9
TC
687 if ($input{class} eq 'fax') {
688 $rc=i_writetiff_wiol($self->{IMG},io_new_fd($fd) );
689 }
690 else {
691 $rc=i_writetiff_wiol_faxable($self->{IMG},io_new_fd($fd) );
692 }
02d1d628
AMH
693 if ( !defined($rc) ) {
694 $self->{ERRSTR}='unable to write tiff image'; return undef;
695 }
696 $self->{DEBUG} && print "writing a tiff file\n";
697 }
698
699 }
700 return $self;
701}
702
703sub write_multi {
704 my ($class, $opts, @images) = @_;
705
706 if ($opts->{type} eq 'gif') {
707 # translate to ImgRaw
708 if (grep !UNIVERSAL::isa($_, 'Imager') || !$_->{IMG}, @images) {
709 $ERRSTR = "Usage: Imager->write_multi({ options }, @images)";
710 return 0;
711 }
712 my @work = map $_->{IMG}, @images;
713 if ($opts->{callback}) {
714 # Note: you may need to fix giflib for this one to work
715 my $maxbuffer = $opts->{maxbuffer};
716 defined $maxbuffer or $maxbuffer = -1; # max by default
717 return i_writegif_callback($opts->{callback}, $maxbuffer,
718 $opts, @work);
719 }
720 if ($opts->{fd}) {
721 return i_writegif_gen($opts->{fd}, $opts, @work);
722 }
723 else {
724 my $fh = IO::File->new($opts->{file}, "w+");
725 unless ($fh) {
726 $ERRSTR = "Error creating $opts->{file}: $!";
727 return 0;
728 }
729 binmode($fh);
730 return i_writegif_gen(fileno($fh), $opts, @work);
731 }
732 }
733 else {
734 $ERRSTR = "Sorry, write_multi doesn't support $opts->{type} yet";
735 return 0;
736 }
737}
738
739# Destroy an Imager object
740
741sub DESTROY {
742 my $self=shift;
743 # delete $instances{$self};
744 if (defined($self->{IMG})) {
745 i_img_destroy($self->{IMG});
746 undef($self->{IMG});
747 } else {
748# print "Destroy Called on an empty image!\n"; # why did I put this here??
749 }
750}
751
752# Perform an inplace filter of an image
753# that is the image will be overwritten with the data
754
755sub filter {
756 my $self=shift;
757 my %input=@_;
758 my %hsh;
759 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
760
761 if (!$input{type}) { $self->{ERRSTR}='type parameter missing'; return undef; }
762
763 if ( (grep { $_ eq $input{type} } keys %filters) != 1) {
764 $self->{ERRSTR}='type parameter not matching any filter'; return undef;
765 }
766
767 if (defined($filters{$input{type}}{defaults})) {
768 %hsh=('image',$self->{IMG},%{$filters{$input{type}}{defaults}},%input);
769 } else {
770 %hsh=('image',$self->{IMG},%input);
771 }
772
773 my @cs=@{$filters{$input{type}}{callseq}};
774
775 for(@cs) {
776 if (!defined($hsh{$_})) {
777 $self->{ERRSTR}="missing parameter '$_' for filter ".$input{type}; return undef;
778 }
779 }
780
781 &{$filters{$input{type}}{callsub}}(%hsh);
782
783 my @b=keys %hsh;
784
785 $self->{DEBUG} && print "callseq is: @cs\n";
786 $self->{DEBUG} && print "matching callseq is: @b\n";
787
788 return $self;
789}
790
791# Scale an image to requested size and return the scaled version
792
793sub scale {
794 my $self=shift;
795 my %opts=(scalefactor=>0.5,type=>'max',qtype=>'normal',@_);
796 my $img = Imager->new();
797 my $tmp = Imager->new();
798
799 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
800
801 if ($opts{xpixels} and $opts{ypixels} and $opts{type}) {
802 my ($xpix,$ypix)=( $opts{xpixels}/$self->getwidth() , $opts{ypixels}/$self->getheight() );
803 if ($opts{type} eq 'min') { $opts{scalefactor}=min($xpix,$ypix); }
804 if ($opts{type} eq 'max') { $opts{scalefactor}=max($xpix,$ypix); }
805 } elsif ($opts{xpixels}) { $opts{scalefactor}=$opts{xpixels}/$self->getwidth(); }
806 elsif ($opts{ypixels}) { $opts{scalefactor}=$opts{ypixels}/$self->getheight(); }
807
808 if ($opts{qtype} eq 'normal') {
809 $tmp->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
810 if ( !defined($tmp->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
811 $img->{IMG}=i_scaleaxis($tmp->{IMG},$opts{scalefactor},1);
812 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
813 return $img;
814 }
815 if ($opts{'qtype'} eq 'preview') {
816 $img->{IMG}=i_scale_nn($self->{IMG},$opts{'scalefactor'},$opts{'scalefactor'});
817 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
818 return $img;
819 }
820 $self->{ERRSTR}='scale: invalid value for qtype'; return undef;
821}
822
823# Scales only along the X axis
824
825sub scaleX {
826 my $self=shift;
827 my %opts=(scalefactor=>0.5,@_);
828
829 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
830
831 my $img = Imager->new();
832
833 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getwidth(); }
834
835 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
836 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},0);
837
838 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
839 return $img;
840}
841
842# Scales only along the Y axis
843
844sub scaleY {
845 my $self=shift;
846 my %opts=(scalefactor=>0.5,@_);
847
848 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
849
850 my $img = Imager->new();
851
852 if ($opts{pixels}) { $opts{scalefactor}=$opts{pixels}/$self->getheight(); }
853
854 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
855 $img->{IMG}=i_scaleaxis($self->{IMG},$opts{scalefactor},1);
856
857 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='unable to scale image'; return undef; }
858 return $img;
859}
860
861
862# Transform returns a spatial transformation of the input image
863# this moves pixels to a new location in the returned image.
864# NOTE - should make a utility function to check transforms for
865# stack overruns
866
867sub transform {
868 my $self=shift;
869 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
870 my %opts=@_;
871 my (@op,@ropx,@ropy,$iop,$or,@parm,$expr,@xt,@yt,@pt,$numre);
872
873# print Dumper(\%opts);
874# xopcopdes
875
876 if ( $opts{'xexpr'} and $opts{'yexpr'} ) {
877 if (!$I2P) {
878 eval ("use Affix::Infix2Postfix;");
879 print $@;
880 if ( $@ ) {
881 $self->{ERRSTR}='transform: expr given and Affix::Infix2Postfix is not avaliable.';
882 return undef;
883 }
884 $I2P=Affix::Infix2Postfix->new('ops'=>[{op=>'+',trans=>'Add'},
885 {op=>'-',trans=>'Sub'},
886 {op=>'*',trans=>'Mult'},
887 {op=>'/',trans=>'Div'},
888 {op=>'-',type=>'unary',trans=>'u-'},
889 {op=>'**'},
890 {op=>'func',type=>'unary'}],
891 'grouping'=>[qw( \( \) )],
892 'func'=>[qw( sin cos )],
893 'vars'=>[qw( x y )]
894 );
895 }
896
897 @xt=$I2P->translate($opts{'xexpr'});
898 @yt=$I2P->translate($opts{'yexpr'});
899
900 $numre=$I2P->{'numre'};
901 @pt=(0,0);
902
903 for(@xt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'xopcodes'}},'Parm',$#pt); } else { push(@{$opts{'xopcodes'}},$_); } }
904 for(@yt) { if (/$numre/) { push(@pt,$_); push(@{$opts{'yopcodes'}},'Parm',$#pt); } else { push(@{$opts{'yopcodes'}},$_); } }
905 @{$opts{'parm'}}=@pt;
906 }
907
908# print Dumper(\%opts);
909
910 if ( !exists $opts{'xopcodes'} or @{$opts{'xopcodes'}}==0) {
911 $self->{ERRSTR}='transform: no xopcodes given.';
912 return undef;
913 }
914
915 @op=@{$opts{'xopcodes'}};
916 for $iop (@op) {
917 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
918 $self->{ERRSTR}="transform: illegal opcode '$_'.";
919 return undef;
920 }
921 push(@ropx,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
922 }
923
924
925# yopcopdes
926
927 if ( !exists $opts{'yopcodes'} or @{$opts{'yopcodes'}}==0) {
928 $self->{ERRSTR}='transform: no yopcodes given.';
929 return undef;
930 }
931
932 @op=@{$opts{'yopcodes'}};
933 for $iop (@op) {
934 if (!defined ($OPCODES{$iop}) and ($iop !~ /^\d+$/) ) {
935 $self->{ERRSTR}="transform: illegal opcode '$_'.";
936 return undef;
937 }
938 push(@ropy,(exists $OPCODES{$iop}) ? @{$OPCODES{$iop}} : $iop );
939 }
940
941#parameters
942
943 if ( !exists $opts{'parm'}) {
944 $self->{ERRSTR}='transform: no parameter arg given.';
945 return undef;
946 }
947
948# print Dumper(\@ropx);
949# print Dumper(\@ropy);
950# print Dumper(\@ropy);
951
952 my $img = Imager->new();
953 $img->{IMG}=i_transform($self->{IMG},\@ropx,\@ropy,$opts{'parm'});
954 if ( !defined($img->{IMG}) ) { $self->{ERRSTR}='transform: failed'; return undef; }
955 return $img;
956}
957
958
959{
960 my $got_expr;
961 sub transform2 {
962 my ($opts, @imgs) = @_;
963
964 if (!$got_expr) {
965 # this is fairly big, delay loading it
966 eval "use Imager::Expr";
967 die $@ if $@;
968 ++$got_expr;
969 }
970
971 $opts->{variables} = [ qw(x y) ];
972 my ($width, $height) = @{$opts}{qw(width height)};
973 if (@imgs) {
974 $width ||= $imgs[0]->getwidth();
975 $height ||= $imgs[0]->getheight();
976 my $img_num = 1;
977 for my $img (@imgs) {
978 $opts->{constants}{"w$img_num"} = $img->getwidth();
979 $opts->{constants}{"h$img_num"} = $img->getheight();
980 $opts->{constants}{"cx$img_num"} = $img->getwidth()/2;
981 $opts->{constants}{"cy$img_num"} = $img->getheight()/2;
982 ++$img_num;
983 }
984 }
985 if ($width) {
986 $opts->{constants}{w} = $width;
987 $opts->{constants}{cx} = $width/2;
988 }
989 else {
990 $Imager::ERRSTR = "No width supplied";
991 return;
992 }
993 if ($height) {
994 $opts->{constants}{h} = $height;
995 $opts->{constants}{cy} = $height/2;
996 }
997 else {
998 $Imager::ERRSTR = "No height supplied";
999 return;
1000 }
1001 my $code = Imager::Expr->new($opts);
1002 if (!$code) {
1003 $Imager::ERRSTR = Imager::Expr::error();
1004 return;
1005 }
1006
1007 my $img = Imager->new();
1008 $img->{IMG} = i_transform2($opts->{width}, $opts->{height}, $code->code(),
1009 $code->nregs(), $code->cregs(),
1010 [ map { $_->{IMG} } @imgs ]);
1011 if (!defined $img->{IMG}) {
1012 $Imager::ERRSTR = "transform2 failed";
1013 return;
1014 }
1015
1016 return $img;
1017 }
1018}
1019
1020
1021
1022
1023
1024
1025
1026
1027sub rubthrough {
1028 my $self=shift;
1029 my %opts=(tx=>0,ty=>0,@_);
1030
1031 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1032 unless ($opts{src} && $opts{src}->{IMG}) { $self->{ERRSTR}='empty input image for source'; return undef; }
1033
1034 i_rubthru($self->{IMG}, $opts{src}->{IMG}, $opts{tx},$opts{ty});
1035 return $self;
1036}
1037
1038
142c26ff
AMH
1039sub flip {
1040 my $self = shift;
1041 my %opts = @_;
9191e525 1042 my %xlate = (h=>0, v=>1, hv=>2, vh=>2);
142c26ff
AMH
1043 my $dir;
1044 return () unless defined $opts{'dir'} and defined $xlate{$opts{'dir'}};
1045 $dir = $xlate{$opts{'dir'}};
1046 return $self if i_flipxy($self->{IMG}, $dir);
1047 return ();
1048}
1049
1050
02d1d628
AMH
1051
1052# These two are supported for legacy code only
1053
1054sub i_color_new {
1055 return Imager::Color->new($_[0], $_[1], $_[2], $_[3]);
1056}
1057
1058sub i_color_set {
1059 return Imager::Color::set($_[0], $_[1], $_[2], $_[3], $_[4]);
1060}
1061
1062
1063
1064# Draws a box between the specified corner points.
1065
1066sub box {
1067 my $self=shift;
1068 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1069 my $dflcl=i_color_new(255,255,255,255);
1070 my %opts=(color=>$dflcl,xmin=>0,ymin=>0,xmax=>$self->getwidth()-1,ymax=>$self->getheight()-1,@_);
1071
1072 if (exists $opts{'box'}) {
1073 $opts{'xmin'} = min($opts{'box'}->[0],$opts{'box'}->[2]);
1074 $opts{'xmax'} = max($opts{'box'}->[0],$opts{'box'}->[2]);
1075 $opts{'ymin'} = min($opts{'box'}->[1],$opts{'box'}->[3]);
1076 $opts{'ymax'} = max($opts{'box'}->[1],$opts{'box'}->[3]);
1077 }
1078
1079 if ($opts{filled}) { i_box_filled($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1080 else { i_box($self->{IMG},$opts{xmin},$opts{ymin},$opts{xmax},$opts{ymax},$opts{color}); }
1081 return $self;
1082}
1083
1084# Draws an arc - this routine SUCKS and is buggy - it sometimes doesn't work when the arc is a convex polygon
1085
1086sub arc {
1087 my $self=shift;
1088 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1089 my $dflcl=i_color_new(255,255,255,255);
1090 my %opts=(color=>$dflcl,
1091 'r'=>min($self->getwidth(),$self->getheight())/3,
1092 'x'=>$self->getwidth()/2,
1093 'y'=>$self->getheight()/2,
1094 'd1'=>0, 'd2'=>361, @_);
1095 i_arc($self->{IMG},$opts{'x'},$opts{'y'},$opts{'r'},$opts{'d1'},$opts{'d2'},$opts{'color'});
1096 return $self;
1097}
1098
1099# Draws a line from one point to (but not including) the destination point
1100
1101sub line {
1102 my $self=shift;
1103 my $dflcl=i_color_new(0,0,0,0);
1104 my %opts=(color=>$dflcl,@_);
1105 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1106
1107 unless (exists $opts{x1} and exists $opts{y1}) { $self->{ERRSTR}='missing begining coord'; return undef; }
1108 unless (exists $opts{x2} and exists $opts{y2}) { $self->{ERRSTR}='missing ending coord'; return undef; }
1109
1110 if ($opts{antialias}) {
1111 i_line_aa($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1112 } else {
1113 i_draw($self->{IMG},$opts{x1}, $opts{y1}, $opts{x2}, $opts{y2}, $opts{color});
1114 }
1115 return $self;
1116}
1117
1118# Draws a line between an ordered set of points - It more or less just transforms this
1119# into a list of lines.
1120
1121sub polyline {
1122 my $self=shift;
1123 my ($pt,$ls,@points);
1124 my $dflcl=i_color_new(0,0,0,0);
1125 my %opts=(color=>$dflcl,@_);
1126
1127 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1128
1129 if (exists($opts{points})) { @points=@{$opts{points}}; }
1130 if (!exists($opts{points}) and exists($opts{'x'}) and exists($opts{'y'}) ) {
1131 @points=map { [ $opts{'x'}->[$_],$opts{'y'}->[$_] ] } (0..(scalar @{$opts{'x'}}-1));
1132 }
1133
1134# print Dumper(\@points);
1135
1136 if ($opts{antialias}) {
1137 for $pt(@points) {
1138 if (defined($ls)) { i_line_aa($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1139 $ls=$pt;
1140 }
1141 } else {
1142 for $pt(@points) {
1143 if (defined($ls)) { i_draw($self->{IMG},$ls->[0],$ls->[1],$pt->[0],$pt->[1],$opts{color}); }
1144 $ls=$pt;
1145 }
1146 }
1147 return $self;
1148}
1149
1150# this the multipoint bezier curve
1151# this is here more for testing that actual usage since
1152# this is not a good algorithm. Usually the curve would be
1153# broken into smaller segments and each done individually.
1154
1155sub polybezier {
1156 my $self=shift;
1157 my ($pt,$ls,@points);
1158 my $dflcl=i_color_new(0,0,0,0);
1159 my %opts=(color=>$dflcl,@_);
1160
1161 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1162
1163 if (exists $opts{points}) {
1164 $opts{'x'}=map { $_->[0]; } @{$opts{'points'}};
1165 $opts{'y'}=map { $_->[1]; } @{$opts{'points'}};
1166 }
1167
1168 unless ( @{$opts{'x'}} and @{$opts{'x'}} == @{$opts{'y'}} ) {
1169 $self->{ERRSTR}='Missing or invalid points.';
1170 return;
1171 }
1172
1173 i_bezier_multi($self->{IMG},$opts{'x'},$opts{'y'},$opts{'color'});
1174 return $self;
1175}
1176
1177
1178# destructive border - image is shrunk by one pixel all around
1179
1180sub border {
1181 my ($self,%opts)=@_;
1182 my($tx,$ty)=($self->getwidth()-1,$self->getheight()-1);
1183 $self->polyline('x'=>[0,$tx,$tx,0,0],'y'=>[0,0,$ty,$ty,0],%opts);
1184}
1185
1186
1187# Get the width of an image
1188
1189sub getwidth {
1190 my $self = shift;
1191 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1192 return (i_img_info($self->{IMG}))[0];
1193}
1194
1195# Get the height of an image
1196
1197sub getheight {
1198 my $self = shift;
1199 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1200 return (i_img_info($self->{IMG}))[1];
1201}
1202
1203# Get number of channels in an image
1204
1205sub getchannels {
1206 my $self = shift;
1207 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1208 return i_img_getchannels($self->{IMG});
1209}
1210
1211# Get channel mask
1212
1213sub getmask {
1214 my $self = shift;
1215 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1216 return i_img_getmask($self->{IMG});
1217}
1218
1219# Set channel mask
1220
1221sub setmask {
1222 my $self = shift;
1223 my %opts = @_;
1224 if (!defined($self->{IMG})) { $self->{ERRSTR} = 'image is empty'; return undef; }
1225 i_img_setmask( $self->{IMG} , $opts{mask} );
1226}
1227
1228# Get number of colors in an image
1229
1230sub getcolorcount {
1231 my $self=shift;
1232 my %opts=(maxcolors=>2**30,@_);
1233 if (!defined($self->{IMG})) { $self->{ERRSTR}='image is empty'; return undef; }
1234 my $rc=i_count_colors($self->{IMG},$opts{'maxcolors'});
1235 return ($rc==-1? undef : $rc);
1236}
1237
1238# draw string to an image
1239
1240sub string {
1241 my $self = shift;
1242 unless ($self->{IMG}) { $self->{ERRSTR}='empty input image'; return undef; }
1243
1244 my %input=('x'=>0, 'y'=>0, @_);
1245 $input{string}||=$input{text};
1246
1247 unless(exists $input{string}) {
1248 $self->{ERRSTR}="missing required parameter 'string'";
1249 return;
1250 }
1251
1252 unless($input{font}) {
1253 $self->{ERRSTR}="missing required parameter 'font'";
1254 return;
1255 }
1256
1257 my $aa=1;
1258 my $font=$input{'font'};
1259 my $align=$font->{'align'} unless exists $input{'align'};
1260 my $color=$input{'color'} || $font->{'color'};
1261 my $size=$input{'size'} || $font->{'size'};
1262
1263 if (!defined($size)) { $self->{ERRSTR}='No size parameter and no default in font'; return undef; }
1264
1265 $aa=$font->{'aa'} if exists $font->{'aa'};
1266 $aa=$input{'aa'} if exists $input{'aa'};
1267
1268
1269
1270# unless($font->can('text')) {
1271# $self->{ERRSTR}="font is unable to do what we need";
1272# return;
1273# }
1274
1275# use Data::Dumper;
1276# warn Dumper($font);
1277
1278# print "Channel=".$input{'channel'}."\n";
1279
1280 if ( $font->{'type'} eq 't1' ) {
1281 if ( exists $input{'channel'} ) {
1282 Imager::Font::t1_set_aa_level($aa);
1283 i_t1_cp($self->{IMG},$input{'x'},$input{'y'},
1284 $input{'channel'},$font->{'id'},$size,
1285 $input{'string'},length($input{'string'}),1);
1286 } else {
1287 Imager::Font::t1_set_aa_level($aa);
1288 i_t1_text($self->{IMG},$input{'x'},$input{'y'},
1289 $color,$font->{'id'},$size,
1290 $input{'string'},length($input{'string'}),1);
1291 }
1292 }
1293
1294 if ( $font->{'type'} eq 'tt' ) {
1295 if ( exists $input{'channel'} ) {
1296 i_tt_cp($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$input{'channel'},
1297 $size,$input{'string'},length($input{'string'}),$aa);
1298 } else {
1299 i_tt_text($font->{'id'},$self->{IMG},$input{'x'},$input{'y'},$color,$size,
1300 $input{'string'},length($input{'string'}),$aa);
1301 }
1302 }
1303
1304 return $self;
1305}
1306
1307
1308
1309
1310
1311# Shortcuts that can be exported
1312
1313sub newcolor { Imager::Color->new(@_); }
1314sub newfont { Imager::Font->new(@_); }
1315
1316*NC=*newcolour=*newcolor;
1317*NF=*newfont;
1318
1319*open=\&read;
1320*circle=\&arc;
1321
1322
1323#### Utility routines
1324
1325sub errstr { $_[0]->{ERRSTR} }
1326
1327
1328
1329
1330
1331
1332# Default guess for the type of an image from extension
1333
1334sub def_guess_type {
1335 my $name=lc(shift);
1336 my $ext;
1337 $ext=($name =~ m/\.([^\.]+)$/)[0];
1338 return 'tiff' if ($ext =~ m/^tiff?$/);
1339 return 'jpeg' if ($ext =~ m/^jpe?g$/);
1340 return 'pnm' if ($ext =~ m/^p[pgb]m$/);
1341 return 'png' if ($ext eq "png");
1342 return 'gif' if ($ext eq "gif");
1343 return ();
1344}
1345
1346# get the minimum of a list
1347
1348sub min {
1349 my $mx=shift;
1350 for(@_) { if ($_<$mx) { $mx=$_; }}
1351 return $mx;
1352}
1353
1354# get the maximum of a list
1355
1356sub max {
1357 my $mx=shift;
1358 for(@_) { if ($_>$mx) { $mx=$_; }}
1359 return $mx;
1360}
1361
1362# string stuff for iptc headers
1363
1364sub clean {
1365 my($str)=$_[0];
1366 $str = substr($str,3);
1367 $str =~ s/[\n\r]//g;
1368 $str =~ s/\s+/ /g;
1369 $str =~ s/^\s//;
1370 $str =~ s/\s$//;
1371 return $str;
1372}
1373
1374# A little hack to parse iptc headers.
1375
1376sub parseiptc {
1377 my $self=shift;
1378 my(@sar,$item,@ar);
1379 my($caption,$photogr,$headln,$credit);
1380
1381 my $str=$self->{IPTCRAW};
1382
1383 #print $str;
1384
1385 @ar=split(/8BIM/,$str);
1386
1387 my $i=0;
1388 foreach (@ar) {
1389 if (/^\004\004/) {
1390 @sar=split(/\034\002/);
1391 foreach $item (@sar) {
1392 if ($item =~ m/^x/) {
1393 $caption=&clean($item);
1394 $i++;
1395 }
1396 if ($item =~ m/^P/) {
1397 $photogr=&clean($item);
1398 $i++;
1399 }
1400 if ($item =~ m/^i/) {
1401 $headln=&clean($item);
1402 $i++;
1403 }
1404 if ($item =~ m/^n/) {
1405 $credit=&clean($item);
1406 $i++;
1407 }
1408 }
1409 }
1410 }
1411 return (caption=>$caption,photogr=>$photogr,headln=>$headln,credit=>$credit);
1412}
1413
1414
1415
1416
1417
1418
1419# Autoload methods go after =cut, and are processed by the autosplit program.
1420
14211;
1422__END__
1423# Below is the stub of documentation for your module. You better edit it!
1424
1425=head1 NAME
1426
1427Imager - Perl extension for Generating 24 bit Images
1428
1429=head1 SYNOPSIS
1430
1431 use Imager qw(init);
1432
1433 init();
1434 $img = Imager->new();
1435 $img->open(file=>'image.ppm',type=>'pnm')
1436 || print "failed: ",$img->{ERRSTR},"\n";
1437 $scaled=$img->scale(xpixels=>400,ypixels=>400);
1438 $scaled->write(file=>'sc_image.ppm',type=>'pnm')
1439 || print "failed: ",$scaled->{ERRSTR},"\n";
1440
1441=head1 DESCRIPTION
1442
1443Imager is a module for creating and altering images - It is not meant
1444as a replacement or a competitor to ImageMagick or GD. Both are
1445excellent packages and well supported.
1446
1447=head2 API
1448
1449Almost all functions take the parameters in the hash fashion.
1450Example:
1451
1452 $img->open(file=>'lena.png',type=>'png');
1453
1454or just:
1455
1456 $img->open(file=>'lena.png');
1457
1458=head2 Basic concept
1459
1460An Image object is created with C<$img = Imager-E<gt>new()> Should
1461this fail for some reason an explanation can be found in
1462C<$Imager::ERRSTR> usually error messages are stored in
1463C<$img-E<gt>{ERRSTR}>, but since no object is created this is the only
1464way to give back errors. C<$Imager::ERRSTR> is also used to report
1465all errors not directly associated with an image object. Examples:
1466
1467 $img=Imager->new(); # This is an empty image (size is 0 by 0)
1468 $img->open(file=>'lena.png',type=>'png'); # initializes from file
1469
1470or if you want to create an empty image:
1471
1472 $img=Imager->new(xsize=>400,ysize=>300,channels=>4);
1473
1474This example creates a completely black image of width 400 and
1475height 300 and 4 channels.
1476
1477If you have an existing image, use img_set() to change it's dimensions
1478- this will destroy any existing image data:
1479
1480 $img->img_set(xsize=>500, ysize=>500, channels=>4);
1481
1482Color objects are created by calling the Imager::Color->new()
1483method:
1484
1485 $color = Imager::Color->new($red, $green, $blue);
1486 $color = Imager::Color->new($red, $green, $blue, $alpha);
1487 $color = Imager::Color->new("#C0C0FF"); # html color specification
1488
1489This object can then be passed to functions that require a color parameter.
1490
1491Coordinates in Imager have the origin in the upper left corner. The
1492horizontal coordinate increases to the right and the vertical
1493downwards.
1494
1495=head2 Reading and writing images
1496
1497C<$img-E<gt>read()> generally takes two parameters, 'file' and 'type'.
1498If the type of the file can be determined from the suffix of the file
1499it can be omitted. Format dependant parameters are: For images of
1500type 'raw' two extra parameters are needed 'xsize' and 'ysize', if the
1501'channel' parameter is omitted for type 'raw' it is assumed to be 3.
1502gif and png images might have a palette are converted to truecolor bit
1503when read. Alpha channel is preserved for png images irregardless of
1504them being in RGB or gray colorspace. Similarly grayscale jpegs are
1505one channel images after reading them. For jpeg images the iptc
1506header information (stored in the APP13 header) is avaliable to some
1507degree. You can get the raw header with C<$img-E<gt>{IPTCRAW}>, but
1508you can also retrieve the most basic information with
d2dfdcc9
TC
1509C<%hsh=$img-E<gt>parseiptc()> as always patches are welcome. pnm has no
1510extra options. Examples:
02d1d628
AMH
1511
1512 $img = Imager->new();
1513 $img->read(file=>"cover.jpg") or die $img->errstr; # gets type from name
1514
1515 $img = Imager->new();
1516 { local(*FH,$/); open(FH,"file.gif") or die $!; $a=<FH>; }
1517 $img->read(data=>$a,type=>'gif') or die $img->errstr;
1518
1519The second example shows how to read an image from a scalar, this is
1520usefull if your data originates from somewhere else than a filesystem
1521such as a database over a DBI connection.
1522
d2dfdcc9
TC
1523When writing to a tiff image file you can also specify the 'class'
1524parameter, which can currently take a single value, "fax". If class
1525is set to fax then a tiff image which should be suitable for faxing
1526will be written. For the best results start with a grayscale image.
1527
a59ffd27
TC
1528If you are reading from a gif image file, you can supply a 'colors'
1529parameter which must be a reference to a scalar. The referenced
1530scalar will receive an array reference which contains the colors, each
e72d3bb1 1531represented as an Imager::Color object.
a59ffd27 1532
04516c2b
TC
1533If you already have an open file handle, for example a socket or a
1534pipe, you can specify the 'fd' parameter instead of supplying a
1535filename. Please be aware that you need to use fileno() to retrieve
1536the file descriptor for the file:
1537
1538 $img->read(fd=>fileno(FILE), type=>'gif') or die $img->errstr;
1539
1540For writing using the 'fd' option you will probably want to set $| for
1541that descriptor, since the writes to the file descriptor bypass Perl's
1542(or the C libraries) buffering. Setting $| should avoid out of order
1543output.
1544
02d1d628
AMH
1545*Note that load() is now an alias for read but will be removed later*
1546
1547C<$img-E<gt>write> has the same interface as C<read()>. The earlier
1548comments on C<read()> for autodetecting filetypes apply. For jpegs
1549quality can be adjusted via the 'jpegquality' parameter (0-100). The
1550number of colorplanes in gifs are set with 'gifplanes' and should be
1551between 1 (2 color) and 8 (256 colors). It is also possible to choose
1552between two quantizing methods with the parameter 'gifquant'. If set
1553to mc it uses the mediancut algorithm from either giflibrary. If set
1554to lm it uses a local means algorithm. It is then possible to give
1555some extra settings. lmdither is the dither deviation amount in pixels
1556(manhattan distance). lmfixed can be an array ref who holds an array
1557of Imager::Color objects. Note that the local means algorithm needs
1558much more cpu time but also gives considerable better results than the
1559median cut algorithm.
1560
1561Currently just for gif files, you can specify various options for the
1562conversion from Imager's internal RGB format to the target's indexed
1563file format. If you set the gifquant option to 'gen', you can use the
1564options specified under L<Quantization options>.
1565
1566To see what Imager is compiled to support the following code snippet
1567is sufficient:
1568
1569 use Imager;
1570 print "@{[keys %Imager::formats]}";
1571
7febf116
TC
1572When reading raw images you need to supply the width and height of the
1573image in the xsize and ysize options:
1574
1575 $img->read(file=>'foo.raw', xsize=>100, ysize=>100)
1576 or die "Cannot read raw image\n";
1577
1578If your input file has more channels than you want, or (as is common),
1579junk in the fourth channel, you can use the datachannels and
1580storechannels options to control the number of channels in your input
1581file and the resulting channels in your image. For example, if your
1582input image uses 32-bits per pixel with red, green, blue and junk
1583values for each pixel you could do:
1584
1585 $img->read(file=>'foo.raw', xsize=>100, ysize=>100, datachannels=>4,
1586 storechannels=>3)
1587 or die "Cannot read raw image\n";
1588
d04ee244
TC
1589Normally the raw image is expected to have the value for channel 1
1590immediately following channel 0 and channel 2 immediately following
1591channel 1 for each pixel. If your input image has all the channel 0
1592values for the first line of the image, followed by all the channel 1
1593values for the first line and so on, you can use the interleave option:
1594
1595 $img->read(file=>'foo.raw', xsize=100, ysize=>100, interleave=>1)
1596 or die "Cannot read raw image\n";
1597
02d1d628
AMH
1598=head2 Multi-image files
1599
1600Currently just for gif files, you can create files that contain more
1601than one image.
1602
1603To do this:
1604
1605 Imager->write_multi(\%opts, @images)
1606
b9029e27 1607Where %opts describes 4 possible types of outputs:
02d1d628 1608
b9029e27
AMH
1609=over 5
1610
1611=item type
1612
1613This is C<gif> for gif animations.
02d1d628
AMH
1614
1615=item callback
1616
1617A code reference which is called with a single parameter, the data to
1618be written. You can also specify $opts{maxbuffer} which is the
1619maximum amount of data buffered. Note that there can be larger writes
1620than this if the file library writes larger blocks. A smaller value
1621maybe useful for writing to a socket for incremental display.
1622
1623=item fd
1624
1625The file descriptor to save the images to.
1626
1627=item file
1628
1629The name of the file to write to.
1630
1631%opts may also include the keys from L<Gif options> and L<Quantization
1632options>.
1633
1634=back
1635
1636The current aim is to support other multiple image formats in the
1637future, such as TIFF, and to support reading multiple images from a
1638single file.
1639
1640A simple example:
1641
1642 my @images;
1643 # ... code to put images in @images
1644 Imager->write_multi({type=>'gif',
1645 file=>'anim.gif',
1646 gif_delays=>[ 10 x @images ] },
1647 @images)
1648 or die "Oh dear!";
1649
1650=head2 Gif options
1651
1652These options can be specified when calling write_multi() for gif
1653files, when writing a single image with the gifquant option set to
1654'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
1655
1656Note that some viewers will ignore some of these options
1657(gif_user_input in particular).
1658
1659=over 4
1660
1661=item gif_each_palette
1662
1663Each image in the gif file has it's own palette if this is non-zero.
1664All but the first image has a local colour table (the first uses the
1665global colour table.
1666
1667=item interlace
1668
1669The images are written interlaced if this is non-zero.
1670
1671=item gif_delays
1672
1673A reference to an array containing the delays between images, in 1/100
1674seconds.
1675
1676=item gif_user_input
1677
1678A reference to an array contains user input flags. If the given flag
1679is non-zero the image viewer should wait for input before displaying
1680the next image.
1681
1682=item gif_disposal
1683
1684A reference to an array of image disposal methods. These define what
1685should be done to the image before displaying the next one. These are
1686integers, where 0 means unspecified, 1 means the image should be left
1687in place, 2 means restore to background colour and 3 means restore to
1688the previous value.
1689
1690=item gif_tran_color
1691
1692A reference to an Imager::Color object, which is the colour to use for
ae235ea6
TC
1693the palette entry used to represent transparency in the palette. You
1694need to set the transp option (see L<Quantization options>) for this
1695value to be used.
02d1d628
AMH
1696
1697=item gif_positions
1698
1699A reference to an array of references to arrays which represent screen
1700positions for each image.
1701
1702=item gif_loop_count
1703
1704If this is non-zero the Netscape loop extension block is generated,
1705which makes the animation of the images repeat.
1706
1707This is currently unimplemented due to some limitations in giflib.
1708
1709=back
1710
1711=head2 Quantization options
1712
1713These options can be specified when calling write_multi() for gif
1714files, when writing a single image with the gifquant option set to
1715'gen', or for direct calls to i_writegif_gen and i_writegif_callback.
1716
1717=over 4
1718
1719=item colors
1720
1721A arrayref of colors that are fixed. Note that some color generators
1722will ignore this.
1723
1724=item transp
1725
1726The type of transparency processing to perform for images with an
1727alpha channel where the output format does not have a proper alpha
1728channel (eg. gif). This can be any of:
1729
1730=over 4
1731
1732=item none
1733
1734No transparency processing is done. (default)
1735
1736=item threshold
1737
1738Pixels more transparent that tr_threshold are rendered as transparent.
1739
1740=item errdiff
1741
1742An error diffusion dither is done on the alpha channel. Note that
1743this is independent of the translation performed on the colour
1744channels, so some combinations may cause undesired artifacts.
1745
1746=item ordered
1747
1748The ordered dither specified by tr_orddith is performed on the alpha
1749channel.
1750
1751=back
1752
ae235ea6
TC
1753This will only be used if the image has an alpha channel, and if there
1754is space in the palette for a transparency colour.
1755
02d1d628
AMH
1756=item tr_threshold
1757
1758The highest alpha value at which a pixel will be made transparent when
1759transp is 'threshold'. (0-255, default 127)
1760
1761=item tr_errdiff
1762
1763The type of error diffusion to perform on the alpha channel when
1764transp is 'errdiff'. This can be any defined error diffusion type
1765except for custom (see errdiff below).
1766
626cabcc 1767=item tr_orddith
02d1d628
AMH
1768
1769The type of ordered dither to perform on the alpha channel when transp
626cabcc 1770is 'ordered'. Possible values are:
02d1d628
AMH
1771
1772=over 4
1773
1774=item random
1775
529ef1f3 1776A semi-random map is used. The map is the same each time.
02d1d628
AMH
1777
1778=item dot8
1779
17808x8 dot dither.
1781
1782=item dot4
1783
17844x4 dot dither
1785
1786=item hline
1787
1788horizontal line dither.
1789
1790=item vline
1791
1792vertical line dither.
1793
1794=item "/line"
1795
1796=item slashline
1797
1798diagonal line dither
1799
1800=item '\line'
1801
1802=item backline
1803
1804diagonal line dither
1805
529ef1f3
TC
1806=item tiny
1807
1808dot matrix dither (currently the default). This is probably the best
1809for displays (like web pages).
1810
02d1d628
AMH
1811=item custom
1812
1813A custom dither matrix is used - see tr_map
1814
1815=back
1816
1817=item tr_map
1818
1819When tr_orddith is custom this defines an 8 x 8 matrix of integers
1820representing the transparency threshold for pixels corresponding to
1821each position. This should be a 64 element array where the first 8
1822entries correspond to the first row of the matrix. Values should be
1823betweern 0 and 255.
1824
1825=item make_colors
1826
1827Defines how the quantization engine will build the palette(s).
1828Currently this is ignored if 'translate' is 'giflib', but that may
1829change. Possible values are:
1830
1831=over 4
1832
1833=item none
1834
1835Only colors supplied in 'colors' are used.
1836
1837=item webmap
1838
1839The web color map is used (need url here.)
1840
1841=item addi
1842
1843The original code for generating the color map (Addi's code) is used.
1844
1845=back
1846
1847Other methods may be added in the future.
1848
1849=item colors
1850
1851A arrayref containing Imager::Color objects, which represents the
1852starting set of colors to use in translating the images. webmap will
1853ignore this. The final colors used are copied back into this array
1854(which is expanded if necessary.)
1855
1856=item max_colors
1857
1858The maximum number of colors to use in the image.
1859
1860=item translate
1861
1862The method used to translate the RGB values in the source image into
1863the colors selected by make_colors. Note that make_colors is ignored
1864whene translate is 'giflib'.
1865
1866Possible values are:
1867
1868=over 4
1869
1870=item giflib
1871
1872The giflib native quantization function is used.
1873
1874=item closest
1875
1876The closest color available is used.
1877
1878=item perturb
1879
1880The pixel color is modified by perturb, and the closest color is chosen.
1881
1882=item errdiff
1883
1884An error diffusion dither is performed.
1885
1886=back
1887
1888It's possible other transate values will be added.
1889
1890=item errdiff
1891
1892The type of error diffusion dither to perform. These values (except
1893for custom) can also be used in tr_errdif.
1894
1895=over 4
1896
1897=item floyd
1898
1899Floyd-Steinberg dither
1900
1901=item jarvis
1902
1903Jarvis, Judice and Ninke dither
1904
1905=item stucki
1906
1907Stucki dither
1908
1909=item custom
1910
1911Custom. If you use this you must also set errdiff_width,
1912errdiff_height and errdiff_map.
1913
1914=back
1915
1916=item errdiff_width
1917
1918=item errdiff_height
1919
1920=item errdiff_orig
1921
1922=item errdiff_map
1923
1924When translate is 'errdiff' and errdiff is 'custom' these define a
1925custom error diffusion map. errdiff_width and errdiff_height define
1926the size of the map in the arrayref in errdiff_map. errdiff_orig is
1927an integer which indicates the current pixel position in the top row
1928of the map.
1929
1930=item perturb
1931
1932When translate is 'perturb' this is the magnitude of the random bias
1933applied to each channel of the pixel before it is looked up in the
1934color table.
1935
1936=back
1937
1938=head2 Obtaining/setting attributes of images
1939
1940To get the size of an image in pixels the C<$img-E<gt>getwidth()> and
1941C<$img-E<gt>getheight()> are used.
1942
1943To get the number of channels in
1944an image C<$img-E<gt>getchannels()> is used. $img-E<gt>getmask() and
1945$img-E<gt>setmask() are used to get/set the channel mask of the image.
1946
1947 $mask=$img->getmask();
1948 $img->setmask(mask=>1+2); # modify red and green only
1949 $img->setmask(mask=>8); # modify alpha only
1950 $img->setmask(mask=>$mask); # restore previous mask
1951
1952The mask of an image describes which channels are updated when some
1953operation is performed on an image. Naturally it is not possible to
1954apply masks to operations like scaling that alter the dimensions of
1955images.
1956
1957It is possible to have Imager find the number of colors in an image
1958by using C<$img-E<gt>getcolorcount()>. It requires memory proportionally
1959to the number of colors in the image so it is possible to have it
1960stop sooner if you only need to know if there are more than a certain number
1961of colors in the image. If there are more colors than asked for
1962the function return undef. Examples:
1963
1964 if (!defined($img->getcolorcount(maxcolors=>512)) {
1965 print "Less than 512 colors in image\n";
1966 }
1967
1968=head2 Drawing Methods
1969
1970IMPLEMENTATION MORE OR LESS DONE CHECK THE TESTS
02d1d628
AMH
1971DOCUMENTATION OF THIS SECTION OUT OF SYNC
1972
1973It is possible to draw with graphics primitives onto images. Such
1974primitives include boxes, arcs, circles and lines. A reference
1975oriented list follows.
1976
1977Box:
1978 $img->box(color=>$blue,xmin=>10,ymin=>30,xmax=>200,ymax=>300,filled=>1);
1979
1980The above example calls the C<box> method for the image and the box
1981covers the pixels with in the rectangle specified. If C<filled> is
1982ommited it is drawn as an outline. If any of the edges of the box are
1983ommited it will snap to the outer edge of the image in that direction.
1984Also if a color is omitted a color with (255,255,255,255) is used
1985instead.
1986
1987Arc:
1988 $img->arc(color=>$red, r=20, x=>200, y=>100, d1=>10, d2=>20 );
1989
1990This creates a filled red arc with a 'center' at (200, 100) and spans
199110 degrees and the slice has a radius of 20. SEE section on BUGS.
1992
1993Circle:
1994 $img->circle(color=>$green, r=50, x=>200, y=>100);
1995
1996This creates a green circle with its center at (200, 100) and has a
1997radius of 20.
1998
1999Line:
2000 $img->line(color=>$green, x1=10, x2=>100,
2001 y1=>20, y2=>50, antialias=>1 );
2002
2003That draws an antialiased line from (10,100) to (20,50).
2004
2005Polyline:
2006 $img->polyline(points=>[[$x0,$y0],[$x1,$y1],[$x2,$y2]],color=>$red);
2007 $img->polyline(x=>[$x0,$x1,$x2], y=>[$y0,$y1,$y2], antialias=>1);
2008
2009Polyline is used to draw multilple lines between a series of points.
2010The point set can either be specified as an arrayref to an array of
2011array references (where each such array represents a point). The
2012other way is to specify two array references.
2013
2014=head2 Text rendering
2015
2016Text rendering is described in the Imager::Font manpage.
2017
2018=head2 Image resizing
2019
2020To scale an image so porportions are maintained use the
2021C<$img-E<gt>scale()> method. if you give either a xpixels or ypixels
2022parameter they will determine the width or height respectively. If
2023both are given the one resulting in a larger image is used. example:
2024C<$img> is 700 pixels wide and 500 pixels tall.
2025
2026 $img->scale(xpixels=>400); # 400x285
2027 $img->scale(ypixels=>400); # 560x400
2028
2029 $img->scale(xpixels=>400,ypixels=>400); # 560x400
2030 $img->scale(xpixels=>400,ypixels=>400,type=>min); # 400x285
2031
2032 $img->scale(scalefactor=>0.25); 175x125 $img->scale(); # 350x250
2033
2034if you want to create low quality previews of images you can pass
2035C<qtype=E<gt>'preview'> to scale and it will use nearest neighbor
2036sampling instead of filtering. It is much faster but also generates
2037worse looking images - especially if the original has a lot of sharp
2038variations and the scaled image is by more than 3-5 times smaller than
2039the original.
2040
2041If you need to scale images per axis it is best to do it simply by
2042calling scaleX and scaleY. You can pass either 'scalefactor' or
2043'pixels' to both functions.
2044
2045Another way to resize an image size is to crop it. The parameters
2046to crop are the edges of the area that you want in the returned image.
2047If a parameter is omited a default is used instead.
2048
2049 $newimg = $img->crop(left=>50, right=>100, top=>10, bottom=>100);
2050 $newimg = $img->crop(left=>50, top=>10, width=>50, height=>90);
2051 $newimg = $img->crop(left=>50, right=>100); # top
2052
2053You can also specify width and height parameters which will produce a
2054new image cropped from the center of the input image, with the given
2055width and height.
2056
2057 $newimg = $img->crop(width=>50, height=>50);
2058
2059The width and height parameters take precedence over the left/right
2060and top/bottom parameters respectively.
2061
2062=head2 Copying images
2063
2064To create a copy of an image use the C<copy()> method. This is usefull
2065if you want to keep an original after doing something that changes the image
2066inplace like writing text.
2067
2068 $img=$orig->copy();
2069
2070To copy an image to onto another image use the C<paste()> method.
2071
2072 $dest->paste(left=>40,top=>20,img=>$logo);
2073
2074That copies the entire C<$logo> image onto the C<$dest> image so that the
2075upper left corner of the C<$logo> image is at (40,20).
2076
142c26ff
AMH
2077
2078=head2 Flipping images
2079
2080An inplace horizontal or vertical flip is possible by calling the
9191e525
AMH
2081C<flip()> method. If the original is to be preserved it's possible to
2082make a copy first. The only parameter it takes is the C<dir>
2083parameter which can take the values C<h>, C<v>, C<vh> and C<hv>.
142c26ff 2084
9191e525
AMH
2085 $img->flip(dir=>"h"); # horizontal flip
2086 $img->flip(dir=>"vh"); # vertical and horizontal flip
2087 $nimg = $img->copy->flip(dir=>"v"); # make a copy and flip it vertically
142c26ff 2088
9191e525 2089=head2 Blending Images
142c26ff 2090
9191e525 2091To put an image or a part of an image directly
142c26ff
AMH
2092into another it is best to call the C<paste()> method on the image you
2093want to add to.
02d1d628
AMH
2094
2095 $img->paste(img=>$srcimage,left=>30,top=>50);
2096
2097That will take paste C<$srcimage> into C<$img> with the upper
2098left corner at (30,50). If no values are given for C<left>
2099or C<top> they will default to 0.
2100
2101A more complicated way of blending images is where one image is
2102put 'over' the other with a certain amount of opaqueness. The
2103method that does this is rubthrough.
2104
2105 $img->rubthrough(src=>$srcimage,tx=>30,ty=>50);
2106
2107That will take the image C<$srcimage> and overlay it with the
2108upper left corner at (30,50). The C<$srcimage> must be a 4 channel
2109image. The last channel is used as an alpha channel.
2110
2111
2112=head2 Filters
2113
2114A special image method is the filter method. An example is:
2115
2116 $img->filter(type=>'autolevels');
2117
2118This will call the autolevels filter. Here is a list of the filters
2119that are always avaliable in Imager. This list can be obtained by
2120running the C<filterlist.perl> script that comes with the module
2121source.
2122
2123 Filter Arguments
2124 turbnoise
2125 autolevels lsat(0.1) usat(0.1) skew(0)
2126 radnoise
2127 noise amount(3) subtype(0)
2128 contrast intensity
2129 hardinvert
2130 gradgen xo yo colors dist
2131
2132The default values are in parenthesis. All parameters must have some
2133value but if a parameter has a default value it may be omitted when
2134calling the filter function.
2135
2136FIXME: make a seperate pod for filters?
2137
2138=head2 Transformations
2139
2140Another special image method is transform. It can be used to generate
2141warps and rotations and such features. It can be given the operations
2142in postfix notation or the module Affix::Infix2Postfix can be used.
2143Look in the test case t/t55trans.t for an example.
2144
2145transform() needs expressions (or opcodes) that determine the source
2146pixel for each target pixel. Source expressions are infix expressions
2147using any of the +, -, *, / or ** binary operators, the - unary
2148operator, ( and ) for grouping and the sin() and cos() functions. The
2149target pixel is input as the variables x and y.
2150
2151You specify the x and y expressions as xexpr and yexpr respectively.
2152You can also specify opcodes directly, but that's magic deep enough
2153that you can look at the source code.
2154
2155You can still use the transform() function, but the transform2()
2156function is just as fast and is more likely to be enhanced and
2157maintained.
2158
2159Later versions of Imager also support a transform2() class method
2160which allows you perform a more general set of operations, rather than
2161just specifying a spatial transformation as with the transform()
2162method, you can also perform colour transformations, image synthesis
2163and image combinations.
2164
2165transform2() takes an reference to an options hash, and a list of
2166images to operate one (this list may be empty):
2167
2168 my %opts;
2169 my @imgs;
2170 ...
2171 my $img = Imager::transform2(\%opts, @imgs)
2172 or die "transform2 failed: $Imager::ERRSTR";
2173
2174The options hash may define a transformation function, and optionally:
2175
2176=over 4
2177
2178=item *
2179
2180width - the width of the image in pixels. If this isn't supplied the
2181width of the first input image is used. If there are no input images
2182an error occurs.
2183
2184=item *
2185
2186height - the height of the image in pixels. If this isn't supplied
2187the height of the first input image is used. If there are no input
2188images an error occurs.
2189
2190=item *
2191
2192constants - a reference to hash of constants to define for the
2193expression engine. Some extra constants are defined by Imager
2194
2195=back
2196
2197The tranformation function is specified using either the expr or
2198rpnexpr member of the options.
2199
2200=over 4
2201
2202=item Infix expressions
2203
2204You can supply infix expressions to transform 2 with the expr keyword.
2205
2206$opts{expr} = 'return getp1(w-x, h-y)'
2207
2208The 'expression' supplied follows this general grammar:
2209
2210 ( identifier '=' expr ';' )* 'return' expr
2211
2212This allows you to simplify your expressions using variables.
2213
2214A more complex example might be:
2215
2216$opts{expr} = 'pix = getp1(x,y); return if(value(pix)>0.8,pix*0.8,pix)'
2217
2218Currently to use infix expressions you must have the Parse::RecDescent
2219module installed (available from CPAN). There is also what might be a
2220significant delay the first time you run the infix expression parser
2221due to the compilation of the expression grammar.
2222
2223=item Postfix expressions
2224
2225You can supply postfix or reverse-polish notation expressions to
2226transform2() through the rpnexpr keyword.
2227
2228The parser for rpnexpr emulates a stack machine, so operators will
2229expect to see their parameters on top of the stack. A stack machine
2230isn't actually used during the image transformation itself.
2231
2232You can store the value at the top of the stack in a variable called
2233foo using !foo and retrieve that value again using @foo. The !foo
2234notation will pop the value from the stack.
2235
2236An example equivalent to the infix expression above:
2237
2238 $opts{rpnexpr} = 'x y getp1 !pix @pix value 0.8 gt @pix 0.8 * @pix ifp'
2239
2240=back
2241
2242transform2() has a fairly rich range of operators.
2243
2244=over 4
2245
2246=item +, *, -, /, %, **
2247
2248multiplication, addition, subtraction, division, remainder and
2249exponentiation. Multiplication, addition and subtraction can be used
2250on colour values too - though you need to be careful - adding 2 white
2251values together and multiplying by 0.5 will give you grey, not white.
2252
2253Division by zero (or a small number) just results in a large number.
2254Modulo zero (or a small number) results in zero.
2255
2256=item sin(N), cos(N), atan2(y,x)
2257
2258Some basic trig functions. They work in radians, so you can't just
2259use the hue values.
2260
2261=item distance(x1, y1, x2, y2)
2262
2263Find the distance between two points. This is handy (along with
2264atan2()) for producing circular effects.
2265
2266=item sqrt(n)
2267
2268Find the square root. I haven't had much use for this since adding
2269the distance() function.
2270
2271=item abs(n)
2272
2273Find the absolute value.
2274
2275=item getp1(x,y), getp2(x,y), getp3(x, y)
2276
2277Get the pixel at position (x,y) from the first, second or third image
2278respectively. I may add a getpn() function at some point, but this
2279prevents static checking of the instructions against the number of
2280images actually passed in.
2281
2282=item value(c), hue(c), sat(c), hsv(h,s,v)
2283
2284Separates a colour value into it's value (brightness), hue (colour)
2285and saturation elements. Use hsv() to put them back together (after
2286suitable manipulation).
2287
2288=item red(c), green(c), blue(c), rgb(r,g,b)
2289
2290Separates a colour value into it's red, green and blue colours. Use
2291rgb(r,g,b) to put it back together.
2292
2293=item int(n)
2294
2295Convert a value to an integer. Uses a C int cast, so it may break on
2296large values.
2297
2298=item if(cond,ntrue,nfalse), if(cond,ctrue,cfalse)
2299
2300A simple (and inefficient) if function.
2301
2302=item <=,<,==,>=,>,!=
2303
2304Relational operators (typically used with if()). Since we're working
2305with floating point values the equalities are 'near equalities' - an
2306epsilon value is used.
2307
2308=item &&, ||, not(n)
2309
2310Basic logical operators.
2311
2312=back
2313
2314A few examples:
2315
2316=over 4
2317
2318=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat x y getp1 !pix @pix sat 0.7 gt @pat @pix ifp'
2319
2320tiles a smaller version of the input image over itself where the colour has a saturation over 0.7.
2321
2322=item rpnexpr=>'x 25 % 15 * y 35 % 10 * getp1 !pat y 360 / !rat x y getp1 1 @rat - pmult @pat @rat pmult padd'
2323
2324tiles the input image over itself so that at the top of the image the
2325full-size image is at full strength and at the bottom the tiling is
2326most visible.
2327
2328=item rpnexpr=>'x y getp1 !pix @pix value 0.96 gt @pix sat 0.1 lt and 128 128 255 rgb @pix ifp'
2329
2330replace pixels that are white or almost white with a palish blue
2331
2332=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'
2333
2334Tiles the input image overitself where the image isn't white or almost
2335white.
2336
2337=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'
2338
2339Produces a spiral.
2340
2341=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'
2342
2343A spiral built on top of a colour wheel.
2344
2345=back
2346
2347For details on expression parsing see L<Imager::Expr>. For details on
2348the virtual machine used to transform the images, see
2349L<Imager::regmach.pod>.
2350
2351=head2 Plugins
2352
2353It is possible to add filters to the module without recompiling the
2354module itself. This is done by using DSOs (Dynamic shared object)
2355avaliable on most systems. This way you can maintain our own filters
2356and not have to get me to add it, or worse patch every new version of
2357the Module. Modules can be loaded AND UNLOADED at runtime. This
2358means that you can have a server/daemon thingy that can do something
2359like:
2360
2361 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2362 %hsh=(a=>35,b=>200,type=>lin_stretch);
2363 $img->filter(%hsh);
2364 unload_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2365 $img->write(type=>'pnm',file=>'testout/t60.jpg')
2366 || die "error in write()\n";
2367
2368Someone decides that the filter is not working as it should -
2369dyntest.c modified and recompiled.
2370
2371 load_plugin("dynfilt/dyntest.so") || die "unable to load plugin\n";
2372 $img->filter(%hsh);
2373
2374An example plugin comes with the module - Please send feedback to
2375addi@umich.edu if you test this.
2376
2377Note: This seems to test ok on the following systems:
2378Linux, Solaris, HPUX, OpenBSD, FreeBSD, TRU64/OSF1, AIX.
2379If you test this on other systems please let me know.
2380
2381=head1 BUGS
2382
2383box, arc, circle do not support antialiasing yet. arc, is only filled
2384as of yet. Some routines do not return $self where they should. This
2385affects code like this, C<$img-E<gt>box()-E<gt>arc()> where an object
2386is expected.
2387
2388When saving Gif images the program does NOT try to shave of extra
2389colors if it is possible. If you specify 128 colors and there are
2390only 2 colors used - it will have a 128 colortable anyway.
2391
2392=head1 AUTHOR
2393
2394Arnar M. Hrafnkelsson, addi@umich.edu
2395And a great deal of help from others - see the README for a complete
2396list.
2397=head1 SEE ALSO
2398
2399perl(1), Imager::Color(3), Affix::Infix2Postfix(3), Parse::RecDescent(3)
2400http://www.eecs.umich.edu/~addi/perl/Imager/
2401
2402
2403=cut