-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderquote.pl
More file actions
executable file
·172 lines (137 loc) · 4.42 KB
/
renderquote.pl
File metadata and controls
executable file
·172 lines (137 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#!/usr/bin/perl
# Turns a bit of text into a single image suitable for display.
require 5;
use diagnostics;
use strict;
use bytes;
use POSIX;
use Fcntl;
use Image::Magick;
use Getopt::Std;
use List::Util qw(max min);
use Data::UUID;
use File::Spec;
my $maxEverPointsize = 0;
my $cline = "$0 @ARGV";
$cline =~ s/\\/\\\\\\/g;
getopts("w:h:f:p:d:t:m:");
our ($opt_w, $opt_h, $opt_f, $opt_p, $opt_d, $opt_t, $opt_m);
my $filetype = $opt_t || "gif"; # File type of resulting image
my $canvasWidth = $opt_w || 800; # Width of output image in pixels
my $canvasHeight = $opt_h || 480; # Height of output image in pixels
my $margin = 18;
my $quoteCount = 0;
my $font = $opt_f || "C:\\windows\\fonts\\ARBERKLEY.ttf"; # Font name
my $prefix = $opt_p || "a"; # Prefix to add to output file name
my $dir = $opt_d || "."; # Directory for output file
my $mpointsize = $opt_m || 60; # Maximum point size
# List of background colors, one will be chosen at random
my @colors = ("green","olive","purple","indigo","brown");
# Read the input text from either a specified file or stdin
my $quotetext = do { local( $/ ) = $ARGV[1]; <> };
# Separate the lines
my @quote = split(/\n/, $quotetext);
# If there was no text, exit
$quotetext || exit(1);
# Get a UUID for a unique output file name
my $ug = Data::UUID->new;
# Construct the path for our output file
my $outpath = File::Spec->catfile( ($dir),
$prefix .
"-" .
$ug->create_str() .
"." .
$filetype );
# Create our output
renderQuote(\@quote, $outpath,
$font,
$colors[int(rand($#colors+1))]);
sub renderQuote
{
my ($quote, $filename, $font, $bgcolor) = @_;
# Text color will be white, unless the background is as well
my $fgcolor = ($bgcolor eq "white" ? "black" : "white");
# Create image object
my $image = Image::Magick->new(size=>"${canvasWidth}x${canvasHeight}");
# Create a blank canvas with our desired background
$image->ReadImage("xc:${bgcolor}");
# Determine what point size will fit
my $pointsize = getQuotePointSize($image,
$quote, $canvasWidth, $margin, $font);
$maxEverPointsize = max($pointsize, $maxEverPointsize);
# Get the size of our output text image
my ($quoteWidth, $quoteHeight) =
getQuoteWidthHeight($image, $quote, $pointsize,$font);
# Based on the sie of our output text image, determine the position on
# the canvas to start writing.
my $x = ($canvasWidth - $quoteWidth)/2;
my $y = ($canvasHeight - ($quoteHeight * 0.85))/2;
my $line;
# Write out each line in the text
foreach $line (@{ $quote }) {
$image->Annotate(
font=>$font,
pointsize=>$pointsize,
fill=>'white',
text=>$line,
'x'=>$x,
'y'=>$y,
fill=>$fgcolor);
# Adjust our positon for the next line based on the height of the
# line we just created
my ($lineWidth, $lineHeight) =
($image->QueryFontMetrics(font=>$font,
pointsize=>$pointsize,text=>$line))[4,5];
$y+=$lineHeight;
}
# Write the image to the file and exit
my $status = $image->Write('filename'=>$filename);
return($status);
}
# Get the total width and height of the quote
sub getQuoteWidthHeight
{
my ($image, $quote, $pointsize, $font) = @_;
my $line;
my $height = 0;
my $width = 0;
my ($textWidth, $textHeight);
foreach $line (@$quote) {
($textWidth, $textHeight) =
($image->QueryFontMetrics(font=>$font,
pointsize=>$pointsize,text=>$line))[4,5];
$width = max($width, $textWidth);
$height += $textHeight;
}
return($width, $height);
}
# Get the largest point size that can render the full quote
sub getQuotePointSize
{
my ($image, $quote, $canvisWidth, $margin, $font) = @_;
my $line;
my @sizes = ();
my $lines = scalar @$quote;
foreach $line (@$quote) {
push(@sizes, getMaxPointSize($image, $line,
$canvasWidth, $margin, $font,$lines));
}
return(min(@sizes));
}
# Get the largest point size that can render the line
sub getMaxPointSize
{
my ($image, $text, $canvasWidth, $margin, $font, $lines) = @_;
my $textWidth;
my $textHeight;
my $pointsize = $mpointsize;
do {
$pointsize--;
($textWidth, $textHeight) =
($image->QueryFontMetrics(font=>$font,
pointsize=>$pointsize,text=>$text))[4,5];
} while (($textWidth + ($margin * 2) > $canvasWidth) ||
(($textHeight * $lines) > ($canvasHeight * 0.85)))
;
return($pointsize);
}