in reply to Re: Image modules not returning or accepting GD::Image
in thread Image modules not returning or accepting GD::Image

G'day Ken

Thank you for your usual thoroughness and helpfulness

just avoid the GD::Image objects altogether

I had actually come up with the same approach to a solution although I hadn't created it. I was thinking that writing a file out to disc and then reading it back in was a messy workaround and that I should be able to avoid using GD::Image using Perl's data structures. But writing the image file definitely works. Good to have my solution validated with your working example :)

In the actual code, I still create a GD::Image so that I can read the width needed to centre the image on the PDF. But that is not used for placing the image, just for working out where it needs to be placed.

Replies are listed 'Best First'.
Re^3: Image modules not returning or accepting GD::Image
by kcott (Archbishop) on Dec 03, 2022 at 02:06 UTC
    "I was thinking that writing a file out to disc and then reading it back in was a messy workaround ..."

    I agree and had the same thought myself. There is a way to do this with in-memory filehandles; however, there were two reasons why I didn't pursue this.

    1. I didn't know if you'd want to reuse the generated image. I see from your "new, additional information" this isn't the case; or, at least, I assume it's not.

      By the way, the "unlink $png_file;" was intended as optional for you and as housekeeping for me; I omitted to specifically state that.

    2. I recalled that you were stuck with a fairly old version of Perl from your ISP. See the "Technical note" in "Opening a filehandle into an in-memory scalar" which may possibly still be a "hurdle" for you.

    As well as a filename, and a GD::Image object when that bug gets fixed, PDF::API2::image() can also take a filehandle. The following code produces exactly the same PDF as my previous code.

    #!/usr/bin/env perl use strict; use warnings; use autodie; use PDF::API2; use GD::Tiler 'tile'; my $pdf_file = 'tiled_dogs.pdf'; my @dog_jpegs = qw{husky.jpg labrador.jpg retriever.jpg}; my $tiled_dogs = tile( Images => [@dog_jpegs], Center => 1, ImagesPerRow => 3, ); my $pdf = PDF::API2::->new(); my $page = $pdf->page(); open my $png_fh, '<:raw', \$tiled_dogs; my $canine_triptych = $pdf->image($png_fh); close $png_fh; $page->object($canine_triptych, 100, 650, 400); $pdf->save($pdf_file);

    Assuming you don't want to keep the generated image, and you're not confronted with technical difficulties, this would be a better solution. I would expect this would also be much faster; but do Benchmark if speed is important to you.

    Update: Two minor tweaks to the code: removed parts left over from the previous script that were no longer needed here.

    — Ken

      Thanks Ken - seeing a working example is extremely helpful.

      My first thought is that I would need to use a pipe but then realised that there doesn't seem to be anything to pipe to...

      You are right, I am using Perl v5.16 (still not moved toa VPS). I will try it without writing out and deleting a file some time but it is not a very high priority as the thing now works and will only get used a couple of times each month. Speed is not at all important - it could take half an hour, and it would still be acceptable.

Re^3: Image modules not returning or accepting GD::Image
by Anonymous Monk on Dec 03, 2022 at 05:25 UTC
    In the actual code, I still create a GD::Image so that I can read the width

    No need. PDF::API2 has methods to get image size. + Using PDF::API2::image_whatever directly is safe, BTW.

    use strict; use warnings; use feature 'say'; use open IO => ':raw'; use GD; use PDF::API2; my $gd_obj = GD::Image-> new( scalar qx/convert rose: png:-/ ); my $pdf = PDF::API2-> new; my $pdf_image = $pdf-> image_gd( $gd_obj ); say $pdf_image-> width; say $pdf_image-> height;

      Ah!
      That's very helpful - thanks