line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Image::ThousandWords; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $NAME = 'Image::ThousandWords'; |
4
|
|
|
|
|
|
|
our $VERSION = '0.10'; |
5
|
|
|
|
|
|
|
our $CHAT = undef; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Image::ThousandWords - convert an image to colored HTML text |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use Image::ThousandWords; |
14
|
|
|
|
|
|
|
my $html = Image::ThousandWords::html( |
15
|
|
|
|
|
|
|
image_path => 'image.jpg', |
16
|
|
|
|
|
|
|
text => 'TurnMeIntoAnImage', |
17
|
|
|
|
|
|
|
}; |
18
|
|
|
|
|
|
|
print "$html\n\n"; |
19
|
|
|
|
|
|
|
exit; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
Or: |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
use Image::ThousandWords; |
24
|
|
|
|
|
|
|
my $o = Image::ThousandWords->new( |
25
|
|
|
|
|
|
|
text => $text, |
26
|
|
|
|
|
|
|
image_path => 'shakespeare.jpg', |
27
|
|
|
|
|
|
|
whitespace => ' ', |
28
|
|
|
|
|
|
|
line_ends => '•', |
29
|
|
|
|
|
|
|
font_size => 20, |
30
|
|
|
|
|
|
|
auto_size => 1, |
31
|
|
|
|
|
|
|
size => 400, |
32
|
|
|
|
|
|
|
font_face => "'Courier New'", |
33
|
|
|
|
|
|
|
); |
34
|
|
|
|
|
|
|
$html = $o->html; |
35
|
|
|
|
|
|
|
print "Content-type:text/html\n\n", $o->wrap_html(background=>'black'); |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
B> for examples of use>. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 DESCRIPTION |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
This module is designed to take as input the path to an image file, |
42
|
|
|
|
|
|
|
and a string of text, and return an HTML colored text, resembling the image made out |
43
|
|
|
|
|
|
|
of the string, repeated as necessary. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Henning Møller-Nielsen wrote the original, Lee Goddard modified it slightly. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Henning said, |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
The inspiration I got from http://www4.telge.kth.se/~d99_kme/ |
50
|
|
|
|
|
|
|
look at http://rto.dk/images/camel.html or http://rto.dk/images/llama.html for the first versions |
51
|
|
|
|
|
|
|
(and I look like this: http://rto.dk/images/henning.htm) |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
Lee adds: |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
Modified by Lee Goddard (lgoddard-at-cpan.org) 2003, and again 15 February 2004 |
56
|
|
|
|
|
|
|
- I did send Henning the mod, but he didn't publish it; I lost it, rewrote it |
57
|
|
|
|
|
|
|
and didn't want to re-write it again. Module now has more parameters, and more |
58
|
|
|
|
|
|
|
control over the HTML, using a combination of CSS and image resizing (the latter |
59
|
|
|
|
|
|
|
being one of Henning's original requests). |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
B> for examples of use>. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=head1 DEPENDENCIES |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
Carp |
66
|
|
|
|
|
|
|
GD |
67
|
|
|
|
|
|
|
Image::Thumbnail |
68
|
|
|
|
|
|
|
HTML::Entities |
69
|
|
|
|
|
|
|
Image::Size |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=cut |
72
|
|
|
|
|
|
|
|
73
|
1
|
|
|
1
|
|
34455
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
33
|
|
74
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
27
|
|
75
|
1
|
|
|
1
|
|
6
|
use Carp "cluck"; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
73
|
|
76
|
1
|
|
|
1
|
|
443
|
use GD; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
use Image::Thumbnail; |
78
|
|
|
|
|
|
|
use HTML::Entities; |
79
|
|
|
|
|
|
|
use Image::Size; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Returns an object blessed into this class |
82
|
|
|
|
|
|
|
sub new { my $class = shift; |
83
|
|
|
|
|
|
|
die unless defined $class and not ref $class; |
84
|
|
|
|
|
|
|
my $self = bless {}, $class; |
85
|
|
|
|
|
|
|
$self->_populate(@_); |
86
|
|
|
|
|
|
|
return $self; |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
sub _populate { my $self = shift; |
90
|
|
|
|
|
|
|
my $args = (ref $_[0]? shift : {@_}); |
91
|
|
|
|
|
|
|
$self->{$_} = $args->{$_} foreach keys %$args; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=head1 CONSTRUCTOR html |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Returns a HTML formatted string, colored to resemble IMAGE. The string consists |
97
|
|
|
|
|
|
|
of the letters and characters from STRING. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Accepts parameters as a hash, list or hash-reference: |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=over 4 |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
=item image_path |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
Path to the file to convert. Must be openable by your version of GD. |
106
|
|
|
|
|
|
|
If you don't supply this, you must supply C as a GD image. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item thumb |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
If you do not supply C (above), you must supply this |
111
|
|
|
|
|
|
|
as a loaded GD image. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=item size |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
The length in pixels of the largest size of the image when |
116
|
|
|
|
|
|
|
re-sized prior to conversion to text. Default is C<100>. |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=item auto_size |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
If set, experimentally tries to re-size the output to be |
121
|
|
|
|
|
|
|
the same size, in pixels, as the input. If supplied, don't |
122
|
|
|
|
|
|
|
bother with C or C (below), but maybe |
123
|
|
|
|
|
|
|
use C (above). |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
So, if you supply C as well as C, you are |
126
|
|
|
|
|
|
|
requesting the output to the be C in pixels, the number |
127
|
|
|
|
|
|
|
of characters in each row being determind by C |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
If you supply C without C, then C |
130
|
|
|
|
|
|
|
specifies the number of characters per row. |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
=item text |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Text to use in conversion of the C. Default is C, |
135
|
|
|
|
|
|
|
so you'd better supply your own. Note that whitesapce will be stripped. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=item whitespace |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
If you don't supply this at all, all whitespace will be removed. |
140
|
|
|
|
|
|
|
If you do supply this, all whitespace will be substituted for whatever |
141
|
|
|
|
|
|
|
this C value is. Intention is that you'll supply a single |
142
|
|
|
|
|
|
|
space to maintain whitespace - or some character to maintain spacing |
143
|
|
|
|
|
|
|
and colouring. See also C below. |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
=item line_ends |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
Replace line terminators C<[\n\r\f]> with this string: may be multiple |
148
|
|
|
|
|
|
|
characters. By default this paramter is set to whatever C |
149
|
|
|
|
|
|
|
is set to - setting this parameter over-rides the effets of the former |
150
|
|
|
|
|
|
|
parameter on line terminators. |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=item font_face |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
String to use in the HTML, which will be quoted in "double-quotes". |
155
|
|
|
|
|
|
|
Defaults to C<'Arial Black','Lucida Console','Courier New', Courier'>. |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
=item font_size |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
Number of pixels for the size of the font used: default is C<8>. |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=item line_height |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
Number of pixels for the height of a line of text. Default value |
164
|
|
|
|
|
|
|
is two pixels less than the C. |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=item scanline_skip |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
You shuldn't need this, but... |
169
|
|
|
|
|
|
|
The number of scan-lines or rows to skip jump in each read of |
170
|
|
|
|
|
|
|
the image. The default is to read every line, which is a C |
171
|
|
|
|
|
|
|
of C<1> - not a very clear name, sorry. Check the relation of this to |
172
|
|
|
|
|
|
|
the C parameter, above. |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=back |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
B> for examples of use>. |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=cut |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub html { |
181
|
|
|
|
|
|
|
local $_; |
182
|
|
|
|
|
|
|
my $self = (ref $_[0] eq __PACKAGE__? shift : __PACKAGE__->new); |
183
|
|
|
|
|
|
|
$self->_populate(@_); |
184
|
|
|
|
|
|
|
unless (defined $self->{image_path} or defined $self->{thumb}){ |
185
|
|
|
|
|
|
|
cluck "No image path" ; |
186
|
|
|
|
|
|
|
return undef; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
$self->{result} = ""; |
189
|
|
|
|
|
|
|
warn "# Image path: ".$self->{image_path} if defined $self->{image_path} and defined $CHAT; |
190
|
|
|
|
|
|
|
$self->{font_size} = 8 unless defined $self->{font_size}; |
191
|
|
|
|
|
|
|
warn "# Font size: ".$self->{font_size} if defined $self->{font_size} and defined $CHAT; |
192
|
|
|
|
|
|
|
$self->{font_face} = "'Arial Black','Lucida Console','Courier New', Courier'" unless defined $self->{font_face}; |
193
|
|
|
|
|
|
|
warn "# Font face: ".$self->{font_face} if defined $self->{font_face} and defined $CHAT; |
194
|
|
|
|
|
|
|
$self->{line_height} = $self->{font_size} - int ($self->{font_size}/3) unless defined $self->{line_height}; |
195
|
|
|
|
|
|
|
warn "# Line height: ".$self->{line_height} if defined $self->{line_height} and defined $CHAT; |
196
|
|
|
|
|
|
|
$self->{scanline_skip} = 1 unless defined $self->{scanline_skip}; |
197
|
|
|
|
|
|
|
warn "# Scanline: ".$self->{scanline_skip} if defined $self->{scanline_skip} and defined $CHAT; |
198
|
|
|
|
|
|
|
$self->{text} = 'aPictureIsWorthAThousandWords' unless defined $self->{text}; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
$self->{whitespace} = "" unless defined $self->{whitespace}; |
201
|
|
|
|
|
|
|
my $whitespace; |
202
|
|
|
|
|
|
|
if ($self->{line_ends}){ |
203
|
|
|
|
|
|
|
$whitespace = '[ |\t]'; |
204
|
|
|
|
|
|
|
$self->{text} =~ s/([\n\r\f])+/$1/sg; # collapse line endings |
205
|
|
|
|
|
|
|
} else { |
206
|
|
|
|
|
|
|
$self->{line_ends} = $self->{whitespace}; |
207
|
|
|
|
|
|
|
$whitespace = '\s' |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
$self->{text} =~ s/${whitespace}+/$self->{whitespace}/smg if defined $self->{whitespace}; |
210
|
|
|
|
|
|
|
my @text = split //, $self->{text}; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# Set size.... |
213
|
|
|
|
|
|
|
if (defined $self->{image_path} and $self->{auto_size}){ |
214
|
|
|
|
|
|
|
my ($x, $y) = imgsize( $self->{image_path} ); |
215
|
|
|
|
|
|
|
unless ($x and $y){ |
216
|
|
|
|
|
|
|
cluck "No x or y?"; |
217
|
|
|
|
|
|
|
return undef; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# Get the size of original |
221
|
|
|
|
|
|
|
if (defined $self->{size}){ |
222
|
|
|
|
|
|
|
my $r = $x>$y ? $x / $self->{size} : $y / $self->{size}; |
223
|
|
|
|
|
|
|
$x /= $r; |
224
|
|
|
|
|
|
|
$y /= $r; |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
warn "# Size is $x,$y" if $CHAT; |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# Set 'size' to longest side of original, over the font_size |
229
|
|
|
|
|
|
|
# - what is wrong with this?! |
230
|
|
|
|
|
|
|
$x /= $self->{font_size}; |
231
|
|
|
|
|
|
|
$y /= $self->{line_height}; |
232
|
|
|
|
|
|
|
$x = int($x)+1 if int($x) != $x; |
233
|
|
|
|
|
|
|
$y = int($y)+1 if int($y) != $y; |
234
|
|
|
|
|
|
|
$self->{size} = $x > $y? $x : $y; |
235
|
|
|
|
|
|
|
warn "# New size from $x,$y is $self->{size}, so lines are $x characters of $self->{font_size}px" if $CHAT; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
elsif (not defined $self->{size}){ |
238
|
|
|
|
|
|
|
$self->{size} = 100; |
239
|
|
|
|
|
|
|
warn "# Set size (B) to: ".$self->{size} if defined $CHAT; |
240
|
|
|
|
|
|
|
} elsif ($self->{size} <= $self->{font_size}){ |
241
|
|
|
|
|
|
|
cluck "Please make sure size ($self->{size}) > font_size ($self->{font_size})"; |
242
|
|
|
|
|
|
|
return undef; |
243
|
|
|
|
|
|
|
} else { |
244
|
|
|
|
|
|
|
warn "# Size (C) is ".$self->{size} if defined $CHAT; |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
# Re-size the image if necessary (ie unless orig interface used) |
248
|
|
|
|
|
|
|
# This is quicker than us trying to work out an average colour for |
249
|
|
|
|
|
|
|
# a block of pixels |
250
|
|
|
|
|
|
|
my $t; |
251
|
|
|
|
|
|
|
unless ($self->{thumb}){ |
252
|
|
|
|
|
|
|
$t = new Image::Thumbnail( |
253
|
|
|
|
|
|
|
module => 'GD', |
254
|
|
|
|
|
|
|
create => 1, |
255
|
|
|
|
|
|
|
size => $self->{size}, |
256
|
|
|
|
|
|
|
inputpath => $self->{image_path}, |
257
|
|
|
|
|
|
|
); |
258
|
|
|
|
|
|
|
$self->{thumb} = $t->{thumb}; |
259
|
|
|
|
|
|
|
undef $t; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
unless (defined $self->{thumb}){ |
263
|
|
|
|
|
|
|
cluck "Could not re-size the image"; |
264
|
|
|
|
|
|
|
return undef; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
my ($x, $y) = $self->{thumb}->getBounds(); |
268
|
|
|
|
|
|
|
my ($R, $G, $B) = (-1); |
269
|
|
|
|
|
|
|
@text = (@text, @text) while ($x*$y > scalar(@text)); |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# Finally do the job |
272
|
|
|
|
|
|
|
my $j; |
273
|
|
|
|
|
|
|
for ($j = 0; $j < $y; $j += $self->{scanline_skip}) { |
274
|
|
|
|
|
|
|
my $i; |
275
|
|
|
|
|
|
|
for ($i = 0; $i < $x; $i++) { |
276
|
|
|
|
|
|
|
my $index = $self->{thumb}->getPixel($i, $j); |
277
|
|
|
|
|
|
|
my ($r,$g,$b) = $self->{thumb}->rgb($index); |
278
|
|
|
|
|
|
|
unless (($r == $R) and ($g == $G) and ($b == $B)) { |
279
|
|
|
|
|
|
|
($R, $G, $B) = ($r, $g, $b); |
280
|
|
|
|
|
|
|
my $color = '#' . sprintf("%.2X%.2X%.2X", $r, $g, $b); |
281
|
|
|
|
|
|
|
$self->{result} .= qq¤¤; |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
my $char; |
284
|
|
|
|
|
|
|
# Do not begin or end a line with whitespace |
285
|
|
|
|
|
|
|
do { |
286
|
|
|
|
|
|
|
$char = shift @text |
287
|
|
|
|
|
|
|
} while (($i==0 or $i==$x-1) and $char eq $self->{whitespace}); |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
if ($self->{line_ends}){ |
290
|
|
|
|
|
|
|
if (not $char =~ s/[\n\r\f]/$self->{line_ends}/){ |
291
|
|
|
|
|
|
|
$char = HTML::Entities::encode($char); |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
} else { |
294
|
|
|
|
|
|
|
$char = HTML::Entities::encode($char); |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
$self->{result} .= $char; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
$self->{result} .= "\n "; |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
if ($self->{result}){ |
303
|
|
|
|
|
|
|
$self->{result} = qq¤¤ |
304
|
|
|
|
|
|
|
. $self->{result} |
305
|
|
|
|
|
|
|
. qq¤\n¤; |
306
|
|
|
|
|
|
|
return $self->{result}; |
307
|
|
|
|
|
|
|
} else { |
308
|
|
|
|
|
|
|
return undef; |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head2 METHOD wrap_html |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
Convenience method to return the C field wrapped in |
315
|
|
|
|
|
|
|
HTML to make a complete page. Accepts values valid for CSS |
316
|
|
|
|
|
|
|
in the parameter C, and text in the C (which |
317
|
|
|
|
|
|
|
is otherwise inherited from the calling object) or the C. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Sets the C field and returns an HTML page. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=cut |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub wrap_html { my ($self, $args) = (shift, (ref $_[0]? shift : {@_})); |
324
|
|
|
|
|
|
|
$args->{background} = "black" unless defined $args->{background}; |
325
|
|
|
|
|
|
|
$self->{title} = $args->{title} if defined $args->{title}; |
326
|
|
|
|
|
|
|
if (not defined $self->{title}){ |
327
|
|
|
|
|
|
|
$self->{title} = $self->{image_path}; |
328
|
|
|
|
|
|
|
($self->{title}) = $self->{title} =~ /([^\\\/]+)\.\w{3,4}$/; |
329
|
|
|
|
|
|
|
$self->{title} =~ s/_+/ /g; |
330
|
|
|
|
|
|
|
} |
331
|
|
|
|
|
|
|
return "\n\n |
332
|
|
|
|
|
|
|
$self->{title} |
333
|
|
|
|
|
|
|
$self->{result} |
334
|
|
|
|
|
|
|
\n"; |
335
|
|
|
|
|
|
|
} |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=head1 BACKWARDS COMPARABILITY |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
The original C module's C method is still acceptable. |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
=cut |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
sub giveme ($$) { |
344
|
|
|
|
|
|
|
return html( |
345
|
|
|
|
|
|
|
thumb => $_[0], |
346
|
|
|
|
|
|
|
text => $_[1], |
347
|
|
|
|
|
|
|
); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
1; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 EXAMPLES FROM HENNING: |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Made with the v. 0.01 (just a script, inspired by http://www4.telge.kth.se/~d99_kme/) |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
http://rto.dk/images/camel.html |
357
|
|
|
|
|
|
|
http://rto.dk/images/llama.html |
358
|
|
|
|
|
|
|
http://rto.dk/images/henning.html (me) |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
Made with the v. 0.03 |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
http://rto.dk/images/neptune.html |
363
|
|
|
|
|
|
|
http://rto.dk/images/mars.html |
364
|
|
|
|
|
|
|
http://rto.dk/images/pluto_charon.html |
365
|
|
|
|
|
|
|
http://rto.dk/images/earth.html |
366
|
|
|
|
|
|
|
http://rto.dk/images/saturn.html |
367
|
|
|
|
|
|
|
http://rto.dk/images/jupiter.html (here the reason for v. 0.04 is apparent) |
368
|
|
|
|
|
|
|
http://rto.dk/images/ira1.html |
369
|
|
|
|
|
|
|
http://rto.dk/images/ira2.html (my colleagues) |
370
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=head1 KNOWN BUGS |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
None, from a perl perspective. From an image perspective things look different :-) |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=head1 AUTHOR ETC. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
Henning Michael Møller-Nielsen, hmn -at- datagraf.dk |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
Slightly modified by Lee Goddard, lgoddard -at- cpan.org |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
=head1 VERSION HISTORY |
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
A bit of an overkill, but hey - this is Fun! |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
0.01 Not really a module, just a script |
386
|
|
|
|
|
|
|
0.02 'ThousandWords.pm' came to life |
387
|
|
|
|
|
|
|
0.03 Fixed an error so the first text in a black image wouldn't be white |
388
|
|
|
|
|
|
|
0.04 Fixed an error so the first text in a black image wouldn't be larger |
389
|
|
|
|
|
|
|
than the rest and so spaces no longer would be used |
390
|
|
|
|
|
|
|
0.05 Ah - added POD |
391
|
|
|
|
|
|
|
0.06 Lee added: re-sizing of image; new access method; proper HTML entities |
392
|
|
|
|
|
|
|
0.07 Sod it - full OO interface, more re-sizing, line-feeds/whitespace |
393
|
|
|
|
|
|
|
0.08 Fixed MANIFEST for test.pl |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
Future: |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
ANSI colored text? |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Work on the 'size' field |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=head1 SEE ALSO |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
L, |
404
|
|
|
|
|
|
|
L, |
405
|
|
|
|
|
|
|
L. |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
B> for examples of use>. |