in reply to Centering Text with GD::Image
Here is some code that does just what you want...it centres two lines of text, one a watermark and one a copyright message, over a GD::Image object $full. It should get you started:
# Centre text components on image
my $colour = $full->colorAllocate(0, 0, 0);
my @bounds = new GD::Image->stringFT($colour, "Image/outline.ttf",
+90, 0.18, 0, 0, $watermark_text);
my $left = ($full->width() / 2) - (($bounds[2] - $bounds[0]) / 2
+) + 5;
my $top = ($full->height() / 2) - ($bounds[7] - $bounds[1]) / 2
+;
$full->stringFT($colour, "/Image/outline.ttf", 90, 0.18, $left, $top,
+$watermark_text);
@bounds = new GD::Image->stringFT($colour, "Image/watermark.ttf
+", 95, 0.18, 0, 0, $copyright);
$left = ($full->width() / 2) - (($bounds[2] - $bounds[0]) / 2) +
+ 5;
$full->stringFT($colour, "Image/watermark.ttf", 95, 0.18, $left, $top
++ 160, $copyright_text);
Re^2: Centering Text with GD::Image
by kcott (Archbishop) on Nov 04, 2021 at 04:31 UTC
|
G'day Bod,
I recall this (or very similar) code from various questions you were asking some months ago.
In isolation, this could be quite confusing;
consider labelling it as an extract and then adding a link back to the original code to provide more context.
However, that's the least of my issues with your post.
Of far greater concern, is posting code like:
new GD::Image->stringFT(...)
Please read "perlobj: Invoking Class Methods" in general;
and specifically the "Indirect Object Syntax" subsection.
Note the emboldened "use of this syntax is discouraged";
and later "We recommend that you avoid this syntax". Reasons are given later in that subsection.
I don't recall your original code in any detail which makes suggesting an absolute fix impossible.
Maybe replace both lines with something closer to:
GD::Image::->new()->stringFT(...)
Or perhaps create one generic, reuseable object:
my $generic_gd_img = GD::Image::->new();
$generic_gd_img->stringFT(...)
There's potentially other ways to handle this, such as returning @bounds from a subroutine;
however, please avoid the indirect syntax in your own code and don't suggest its use to others.
| [reply] [d/l] [select] |
|
avoid the indirect syntax in your own code and don't suggest its use to others.
While I agree with the advice, don't be too hard on people who use that notation for GD -- the GD POD shows indirect object notation in their SYNOPSIS and most (‡) of their code snippets where they show using the new or newFromXXX class methods, even when they show correct method-notation just above the example. Given that poor documentation choice, I can understand why users would pick up the indirect object notation (for those who don't know that indirect object syntax is just an alternate, they might reasonably interpret that the indirect object syntax is required for GD, since so many examples show that syntax).
‡: but not quite all: the code snippets in newFromGd2Part and gifanimbegin each show one instance of method-style notation. But those are the only two instances of ->new* that I could find in the main GD POD code snippets. The rest are all indirect object syntax.
--
edit: created issue rt://139961
| [reply] [d/l] [select] |
|
G'day pryrt,
By quoting me out of context — by removing the leading "please" —
you've turned what was intended as politeness into what looks like a harsh command.
Your first sentence, which includes "don't be too hard on people", strengthens that (incorrect) perception.
There's a lot of poor code posted by CPAN authors;
this doesn't mean that it should be blindly followed in cargo-cult fashion.
The code in the SYNOPSIS of GD, to which you linked, does indeed use indirect syntax.
It also has five package variables.
I'd be reasonably confident that "please don't use package variables, use lexical ones instead"
would not be greeted with "don't be too hard on people".
Furthermore, module POD (and even perldoc code) is generally intended as an example.
It's not littered with strictures, error checking, data validation, and so on.
It is meant to show the guts of what's needed; not Perl Best Practices or anything like that.
Bod has been here almost a year; he'll celebrate his first Monkday on Monday week.
In that time, he's shown an extraordinary eagerness to learn.
I applaud this attitude and, wherever possible, I've attempted to help him.
There was nothing intentionally negative in what I wrote and,
if you look at his reply, you'll see he took no offence (and, in fact, thanked me).
| [reply] |
|
|
|
|
|
|
created issue rt://139961
I put in a pull request for that issue, and within a couple hours, it was merged -- fast response! So the next release of GD will use the updated POD, no longer showing examples with indirect object notation.
| [reply] |
|
Of far greater concern, is posting code like:
new GD::Image->stringFT(...)
Hi Ken,
Thanks for your wise words and useful link. I don't write this form in code that I formulate from scratch...but, no doubt it came from the GD Documentation. I think, but I'm not sure, that this code actually came from an example somewhere on the web rather than directly from the documentation.
Your memory serves you well!
I did post Adding a watermark to an image with GD::Image some time ago and the code I posted was the same code shared above. The indirect syntax was in the original part and you did mention it at the time...I had no idea what the term meant then and didn't get around to looking at it further as getting the watermark colours (the subject of the question) showing correctly was the priority.
I wouldn't use indirect syntax in code I produce from scratch. I don't know why...I just wouldn't do it that way. I will be sure to look more at the links you shared to find out why I shouldn't do it that way...
Fortunately, the code was helpful to djlerman. Hopefully, he will also look into your links...
| [reply] [d/l] |
|
G'day Bod,
"Thanks for your wise words and useful link."
You're very welcome.
When you get around to reading the documentation to which I linked,
you'll see the very good reasons for avoiding indirect syntax.
You will still encounter new Some::Module on CPAN and elsewhere;
I just write Some::Module::->new() and move on.
Code like new Some::Module->method() can be difficult to understand
and, in my opinion, should never appear in modern Perl code.
As the doco explains, Perl itself can have trouble parsing indirect syntax code.
[By the way, you might want to take a peek at
my response to pryrt's reply.]
| [reply] [d/l] [select] |
Re^2: Centering Text with GD::Image
by djlerman (Sexton) on Nov 04, 2021 at 18:41 UTC
|
@Bod
This worked perfectly. Thank You! | [reply] |
|
| [reply] |
|
I think this is the specific code that worked for me. There are a few weird things at the end because I am using EMBPERL.
This is on a CentOS release 6.5 build.
use GD;
$first = "First Name";
$middle = "Middle Name";
$last = "Last Name";
$image = "/www/images/image.jpg";
$im = GD::Image->newFromJpeg($image);
($width, $height) = $im->getBounds();
$outim = new GD::Image($width, $height);
$outim->copyResampled($im, 0, 0, 0, 0, $width, $height, $width, $heigh
+t);
# name
$fgcolor = $outim->colorAllocate(0,0,0);
$fontname = '/usr/share/fonts/dejavu/DejaVuSerif.ttf';
$ptsize = 20;
$angle = 0;
$x = 345;
$y = 275;
$string = ucfirst($first) . ($middle ne '' ? ' ' . ucfirst($middle
+) : '') . ' ' . ucfirst($last);
@bounds = new GD::Image->stringFT($fgcolor,$fontname,$ptsize,$angle,$x
+,$y,$string);
$left = ($outim->width() / 2) - (($bounds[2] - $bounds[0]) / 2) + 5;
$top = ($outim->height() / 2) - ($bounds[7] - $bounds[1]) / 2;
$outim->stringFT($fgcolor, $fontname,$ptsize,$angle,$left,$y,$string);
+
# make sure we are writing to a binary stream
binmode STDOUT;
select(STDOUT);
$| = 1;
undef $/;
$http_headers_out{'Content-Type'} = "image/png";
$escmode = 0;
print OUT $outim->png();
| [reply] [d/l] |
|
|
|