This is PerlMonks "Mobile"

Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Discipulus has asked for the wisdom of the Perl Monks concerning the following question:

Hello folks!

I'm experimenting with images again but I'm stucked at image rotation using GD. Documentation says:

> $image->copyRotated($sourceImage,$dstX,$dstY,$srcX,$srcY,$width,$height,$angle) Like copyResized() but the $angle argument specifies an arbitrary amount to rotate the image clockwise (in degrees). In addition, $dstX and $dstY species the center of the destination image, and not the top left corner.

The following code seems to rotate counter clockwise instead (pass to the following program a jpg image and optionally a degrees value):

use strict; use warnings; use GD; print "GD version : $GD::VERSION\n"; print "libgd version: ",GD::VERSION_STRING,"\n"; my $original_jpg = $ARGV[0]; my $angle = $ARGV[1] ? $ARGV[1] : 90; my $gd = GD::Image->new( $original_jpg ); my $gdrot = new GD::Image($gd->width, $gd->height ); $gdrot->copyRotated( $gd, # source $gd->width/2, # X center of the destinat +ion image $gd->height/2, # Y center of the destinat +ion image 0, # X specify the upper left + corner of a rectangle in the source image 0, # Y specify the upper left + corner of a rectangle in the source image $gd->width, # final width $gd->height, # final height $angle # rotation angle clockwise + in degrees ); open my $fh,'>', "rotated_".$angle."_".$original_jpg or die $!; binmode $fh; print $fh $gdrot->jpeg;

Did you see the same result as me? I see the resulting image rotated 90° counter clockwise (I'd say counter documentwise ;). In early tests I got a warning about older version of gdlib (like: libgd 2.0.33 or higher required for copyRotated ) and I upgraded my GD.pm using cpan client and everything went fine.

I currently have: GD version   : 2.66 libgd version: 2.2.4

Any insight appreciated.

L*

There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Replies are listed 'Best First'.
Re: Image rotation with GD: counter or clockwise?
by rurban (Scribe) on Feb 23, 2021 at 15:59 UTC
    Yep, my docs seem to be wrong. Libgd docs are right. It's a mathematical rotation.
Re: Image rotation with GD: counter or clockwise?
by LanX (Saint) on Feb 23, 2021 at 13:43 UTC
    I don't have GD installed sorry. But ...

    • ... positive rotations in math are anti-clockwise. Probably a glitch in the docs?
    • ... $ARGV[1] ? $ARGV[1] : 90; are you sure you want this? 0 is false, I'd rather //
    Update

    From the underlying docs at: https://libgd.github.io/manuals/2.3.1/files/gd-c.html#gdImageCopyRotated

    The area is counter-clockwise rotated using nearest-neighbor interpolation.

    I'll try to contact the author for clarification. (Update: email sent)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: Image rotation with GD: counter or clockwise? -- FIXED doc
by Discipulus (Canon) on Jan 26, 2022 at 09:59 UTC
    Hello,

    Finally the pull request was merged and now CPAN documentation reflects the real behaviour.

    Thanks to lstein and rurban!!

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Image rotation with GD: counter or clockwise?
by karlgoethebier (Abbot) on Feb 23, 2021 at 20:17 UTC
    my $original_jpg = $ARGV[0]; my $angle = $ARGV[1] ? $ARGV[1] : 90;

    Ouch! This really hurts. With Getopt::Long it should be easy with defaults. Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

      Hello karlgoethebier and LanX too,

      This is not the point.

      defined or // is available iirc since 5.14 and ok it is old. I needed something working and I wanted to add a quick way to pass the angle. Ok it fails for the, in this case, edge case of 0 degrees but with 0 degrees no rotation is even needed so it will be stupid to pass 0 to my SSCE. Too much Short to be a SCE? :)

      My program is already more than 450 lines and I still use Getopt::Long and Tk to set some options. I'm aware of // too; thanks. :)

      L*

      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
        > so it will be stupid to pass 0

        It's better not to expect software (or users) to be smart, even in a draft.°

        > to my SSCE

        why does an SSCCE even need defaults?

        > // is available iirc since 5.14

        defined or $#ARGV are older.*

        FWIW: I don't support KGB's tone here, I'm just saying playing safe is easy here.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        °) I have similar discussion regularly with my clients:

        • "Who would ever do this?"
        • "Sigh ... Wait and see!"
        Half a year later

        • "Who could have ever expected this?"
        • "Sigh ... No one! (and thanks for the salary)"
        updates

        *) BTW 5.10.0 https://perldoc.pl/perl5100delta#Defined-or-operator

        I needed something working and I wanted to add a quick way to pass the angle. Ok it fails for the, in this case, edge case of 0 degrees but with 0 degrees no rotation is even needed so it will be stupid to pass 0 to my SSCE. Too much Short to be a SCE? :)

        I had a recent thread about processing image files, and the expectation of respondents that I should have shown up with an Short, Self-Contained, Correct Example ground it to a halt. Sure, first, to insulate myself from criticism, I got a shorter, more concise version of what I was doing, but I left off that because those don't end up as images on the net, which is the proof in the pudding. The equating of image files and lists of strings works in some places and straight-up ludicrous in others. Then the SSCCE couldn't keep up with changes I was making on the fly, so it turned out to be a great irrelevance. Meanwhile, I flubbed integration and will have to re-do anything I "accomplished." I didn't even do the write-up.

        My program is already more than 450 lines

        That's not a lot between readmore tags. Don't we encourage people to show their source around here?