http://qs321.pair.com?node_id=11119769

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

Hello all,

I'm trying to use PDF API2 to output in landscape and to rotate the text and image accordingly. I have somehow gotten the text to rotate 90% but I can't do the same for the image (it doesn't show on the page). Here's my code:
my $pdf=PDF::API2->new; my $font = $pdf->corefont('Helvetica'); my $page = $pdf->page(); $page->mediabox('A4'); $page->rotate(90); # to landscape my $content = $page->text(); $content->font($font,12); $content->transform( -rotate => 90, -translate => [100,500], ); $content->text("This text should appear on the left half of the A4 + Landscape page"); my $photo = $page->gfx; my $photo_file = $pdf->image_jpeg("image.jpg"); $photo->save; # does not rotate correctly because I don't quite understand the t +ranslate part $photo->transform( -rotate => 90, -translate => [my $_x = 0, my $_y = 0], ); $photo->image($photo_file, 50, 360, 200, 200); $photo->restore; $pdf->saveas("test.pdf"); $pdf->end;

I would like to print the rotated text and image on the left half of the landscape page and then to repeat the same text and image on the right half of the landscape page.

Could anyone help shed some light?

Replies are listed 'Best First'.
Re: PDF API2 - landscape and rotating text and image
by roboticus (Chancellor) on Jul 24, 2020 at 19:36 UTC
Re: PDF API2 - landscape and rotating text and image
by kcott (Archbishop) on Jul 24, 2020 at 22:16 UTC
    "# does not rotate correctly because I don't quite understand the translate part"

    When you rotate the page ($page->rotate(90)) to change from portrait to landscape, the X-Y axes change from horizontal-vertical to vertical-horizontal. The -translate values reference the axes; you need to adjust them for the page rotation change. I suspect this is maybe causing you problems understanding what's going on here: it's neither immediately obvious nor intuitive, so your confusion is unsurprising. I suggest you spend some time playing around with the values to get a feel for this.

    The following code generates a landscape-oriented page which roughly looks like this:

    +-------------------------+
    | Left text    Right text |
    |                         |
    | +------+     +------+   |
    | |  ^^  |     |  ^^  |   |
    | |  ||  |     |  ||  |   |
    | | img1 |     | img2 |   |
    | +------+     +------+   |
    +-------------------------+
    

    I used different text and images purely for testing purposes; obviously, you can use the same text and images on both sides. The images were 64x64 pixel PNGs which had a clear UP direction (to check the rotation).

    You'll no doubt need to change certain values to suit your layout requirements; however, I hope this gives you a solid starting point.

    #!/usr/bin/env perl use strict; use warnings; use autodie; use PDF::API2; my $pdf_file = 'test.pdf'; my $left_text = 'This text on the left.'; my $right_text = 'This text on the right.'; my ($left_img, $right_img) = qw{left.png right.png}; my $pdf = PDF::API2::->new(-file => $pdf_file); my $page = $pdf->page(); $page->mediabox('A4'); $page->rotate(90); my $font = $pdf->corefont('Helvetica'); my @text_cfg = ( { text => $left_text, pos => [50, 40] }, { text => $right_text, pos => [50, 450] }, ); for my $cfg (@text_cfg) { my $text = $page->text(); $text->font($font, 12); $text->transform( -translate => $cfg->{pos}, -rotate => 90, ); $text->text($cfg->{text}); } my @gfx_cfg = ( { img => $pdf->image_png($left_img), pos => [150, 40] }, { img => $pdf->image_png($right_img), pos => [150, 450] }, ); my $gfx = $page->gfx; for my $cfg (@gfx_cfg) { $gfx->save(); $gfx->transform( -translate => $cfg->{pos}, -rotate => 90, ); $gfx->image($cfg->{img}, 0, 0); $gfx->restore(); } $pdf->save();

    — Ken

      Hi Ken,

      Thank you so much for your explanation and great working code! Wouldn't have thought of a For loop to do the left and right tasks.

      I have one question for the line below:

      $gfx->image($cfg->{img}, 0, 0);

      The values of 0,0 - that outputs the image in its original size (am I right?). I tried with values like 200, 200 to get bigger images but the images don't appear. How do I output the images to bigger sizes?

      Thanks you for your great help once again :))

        You should look in PDF::API2::Content for information on image(), transform(), and related methods. In particular, look at the "External Objects" and "Coordinate Transformations" sections.

        The '0, 0' to which you referred are co-ordinates, not sizes. As the code already sets the co-ordinates via the '-translate' option of transform(), further modification of the co-ordinates by image() is not wanted.

        The image() method has a number of forms allowing you to change width, height, and scale. There's also a '-scale' option for transform(). Note that if you change the size, you'll also need to adjust the co-ordinates accordingly.

        — Ken