source: other-projects/image-generation/trunk/annotate.pl@ 21019

Last change on this file since 21019 was 13536, checked in by mdewsnip, 16 years ago

Initial revision

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.8 KB
Line 
1#!/usr/bin/perl
2
3
4BEGIN {
5 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
6 unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
7}
8
9
10use Image::Magick;
11use parsargv;
12
13
14sub main
15{
16 # Parse command line arguments
17 if (!parsargv::parse(\@ARGV,
18 'background_image/.*/xc:white', \$background_image,
19 'image_width/^\d+$/', \$image_width,
20 'image_height/^\d+$/', \$image_height,
21 'stretchable_width', \$stretchable_width,
22 'stretchable_height', \$stretchable_height,
23 'note_if_stretched', \$note_if_stretched,
24 'no_text_height_warnings', \$no_text_height_warnings,
25 'h_align/.*/center', \$h_align,
26 'v_align/.*/bottom', \$v_align,
27 'padding_left/^\d+$/1', \$padding_left,
28 'padding_right/^\d+$/1', \$padding_right,
29 'padding_top/^(\\\-)?\d+$/0', \$padding_top,
30 'padding_bottom/^(\\\-)?\d+$/0', \$padding_bottom,
31 'baseline_offset/^(\\\-)?\d+$/0', \$baseline_offset,
32 'font/.*/', \$font,
33 'font_size/^\d+$/10', \$font_size,
34 'text/.*/', \$text,
35 'text_colour/.*/black', \$text_colour,
36 'output_file/.*/', \$output_file,
37 'verbose', \$verbose)) {
38 print STDERR "Error: Bad command line arguments...\n";
39 die "\n";
40 }
41
42
43 # Create a new image, basing it on the background image
44 my $image = Image::Magick->new(font => $font, pointsize => $font_size);
45 $res = $image->Read($background_image);
46 die "$res" if $res;
47
48 # Check required parameter values are set
49 if (!$image_width) {
50 $image_width = $image->Get('width');
51 }
52 if (!$image_height) {
53 $image_height = $image->Get('height');
54 }
55 if ($h_align ne "left" && $h_align ne "center" && $h_align ne "right") {
56 die "Error: Bad h_align $h_align...\n";
57 }
58 if ($v_align ne "top" && $v_align ne "center" && $v_align ne "bottom") {
59 die "Error: Bad v_align $v_align...\n";
60 }
61
62 # Negative padding values (only top and bottom make sense) must be parsed specially
63 if ($padding_top =~ /^\\\-(\d+)$/) {
64 $padding_top = -$1;
65 }
66 if ($padding_bottom =~ /^\\\-(\d+)$/) {
67 $padding_bottom = -$1;
68 }
69
70 # The baseline offset may be negative also...
71 if ($baseline_offset =~ /^\\\-(\d+)$/) {
72 $baseline_offset = -$1;
73 }
74
75 if (!$font) {
76 die "Error: Font not specified...\n";
77 }
78 if (!$text) {
79 die "Error: Text not specified...\n";
80 }
81 if (!$output_file) {
82 die "Error: Output file not specified...\n";
83 }
84
85 $output_file =~ /\/([^\/]+)$/;
86 my $output_file_name = $1;
87
88 # Calculate the usable image area
89 my $usable_image_width = $image_width - $padding_left - $padding_right;
90 my $usable_image_height = $image_height - $padding_top - $padding_bottom;
91
92 if ($verbose) {
93 print STDERR "\nGenerating: $output_file\n";
94 print STDERR "Pasting \"$text\" ($text_colour) in font $font ($font_size pt) onto $background_image\n";
95 print STDERR "Basic size of $image_width x $image_height minus padding (LRTB: $padding_left $padding_right $padding_top $padding_bottom) gives usable area $usable_image_width x $usable_image_height\n";
96 }
97
98 # Resize the image to the desired size (it may be increased later)
99 $res = $image->Resize(width => $image_width, height => $image_height);
100 die "$res" if $res;
101
102 # Convert the (escaped) text string into a Unicode string
103 my $text_unicode = $text;
104 $text_unicode =~ s/\\(0x([0-9A-F]){4})/chr(oct($1))/ieg;
105
106 # Determine the space required to display the text
107 my $text_width = 0;
108 my $text_height = 0;
109 foreach $line (split(/\\n/, $text_unicode)) {
110 ($x_ppem, $y_ppem, $ascender, $descender, $line_width, $line_height, $max_advance) =
111 $image->QueryFontMetrics(text => $line);
112 $line_height = $line_height - $baseline_offset;
113
114 # Use the longest line as the text width
115 if ($line_width > $text_width) {
116 $text_width = $line_width;
117 }
118 $text_height += $line_height;
119 }
120 print STDERR "Text size is $text_width x $text_height\n" if $verbose;
121
122 # If necessary, expand the image horizontally to fit the text...
123 if ($text_width > $usable_image_width) {
124 # ...provided that 'stretchable_width' has been specified
125 if ($stretchable_width) {
126 $usable_image_width = $text_width;
127 $image_width = $usable_image_width + $padding_left + $padding_right;
128 $res = $image->Resize(width => $image_width);
129 die "$res" if $res;
130
131 if ($note_if_stretched) {
132 print STDERR "NOTE: Image width of $output_file_name was stretched to $image_width...\n";
133 }
134 }
135 else {
136 print STDERR "WARNING: Text width ($text_width) is greater than usable image width ($usable_image_width) for $output_file_name...\n";
137 }
138 }
139
140 # If necessary, expand the image vertically to fit the text...
141 if ($text_height > $usable_image_height) {
142 # ...provided that 'stretchable_height' has been specified
143 if ($stretchable_height) {
144 $usable_image_height = $text_height;
145 $image_height = $usable_image_height + $padding_top + $padding_bottom;
146 $res = $image->Resize(height => $image_height);
147 die "$res" if $res;
148
149 if ($note_if_stretched) {
150 print STDERR "NOTE: Image height of $output_file_name was stretched to $image_height...\n";
151 }
152 }
153 else {
154 print STDERR "WARNING: Text height ($text_height) is greater than usable image height ($usable_image_height) for $output_file_name...\n" unless $no_text_height_warnings;
155 }
156 }
157
158 # Determine where the text should be placed in the y dimension, based on v_align
159 if ($v_align eq "top") {
160 $ypos = $font_size - 1;
161 }
162 elsif ($v_align eq "center") {
163 $ypos = (($usable_image_height - $text_height) / 2) + $font_size - 1;
164 }
165 elsif ($v_align eq "bottom") {
166 $ypos = $usable_image_height - $text_height + $font_size - 1;
167 }
168 $ypos = $ypos + $padding_top;
169
170 # Draw each line of the text onto the image
171 foreach $line (split(/\\n/, $text_unicode)) {
172 ($x_ppem, $y_ppem, $ascender, $descender, $line_width, $line_height, $max_advance) =
173 $image->QueryFontMetrics(text => $line);
174 $line_height = $line_height - $baseline_offset;
175
176 # Determine where the text should be placed in the x dimension, based on h_align
177 if ($h_align eq "left") {
178 $xpos = 0;
179 }
180 elsif ($h_align eq "center") {
181 $xpos = ($usable_image_width - $line_width) / 2;
182 }
183 elsif ($h_align eq "right") {
184 $xpos = $usable_image_width - $line_width;
185 }
186 $xpos = $xpos + $padding_left;
187
188 if ($xpos < 0) {
189 $xpos = 0;
190 }
191
192 # print STDERR "Line coordinates: ($xpos, $ypos)\n";
193
194 # Why, why, oh why it is necessary to do this under Windows?
195 # if ($ENV{'GSDLOS'} =~ /windows/i) {
196 # $res = $image->Annotate(text => $line, encoding => 'UTF-8', fill => $text_colour,
197 # x => -$xpos, y => -$ypos, undercolor => 'white');
198 # die "$res" if $res;
199 # }
200
201 # Draw the line text onto the image
202 $res = $image->Annotate(text => $line, encoding => 'UTF-8', fill => $text_colour,
203 x => $xpos, y => $ypos);
204 die "$res" if $res;
205
206 $ypos = $ypos + $line_height;
207 }
208
209 # Save the image to file
210 $res = $image->Write($output_file);
211 die "$res" if $res;
212}
213
214
215&main();
Note: See TracBrowser for help on using the repository browser.