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