Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Centering Text with GD::Image

by Bod (Parson)
on Nov 03, 2021 at 22:45 UTC ( [id://11138410]=note: print w/replies, xml ) Need Help??


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);

Replies are listed 'Best First'.
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.

    — Ken

      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

        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).

        — Ken

        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.

      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...

        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.]

        — Ken

Re^2: Centering Text with GD::Image
by djlerman (Sexton) on Nov 04, 2021 at 18:41 UTC
    @Bod This worked perfectly. Thank You!
      This worked perfectly. Thank You!

      Glad it worked for you.

      Now you may want to rewrite your working code so that it is improved working code by adopting the great advice from kcott. I shall be modifying the code from which that snippet is taken when I next look at that site. Very soon I expect as we are doing quite a bit of development there!

        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();

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11138410]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2024-04-25 11:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found