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

Hello Monks,

I'm trying to download KeyForge images from the official site with a Perl program. Here is what I got:

use 5.010; use strict; use warnings; use LWP::UserAgent; my $url = "https://cdn.keyforgegame.com/media/card_front/en/341_1_7C85 +4VPW72RH_en.png"; my $ua = LWP::UserAgent->new(agent => ''); my $response = $ua->get($url); die $response->status_line if not $response->is_success; my $data = $response->content; say $data;

Then I start the program with:

perl test.pl > test.png

The resulting file can't unfortunately be opened by applications (error: bad format). I tried to diff my file with the one downloaded with a browser and it shows 8 differences. I'm not used to diff binary files but it seems maybe there's a CRLF conversion somewhere. I'm on Windows by the way.

Could someone help me?

Replies are listed 'Best First'.
Re: Downloading KeyForge image
by afoken (Chancellor) on May 21, 2019 at 18:57 UTC

    On Windows, STDOUT applies "\n" to CRLF conversion by default, breaking binary data. Add binmode STDOUT before writing data to STDOUT and it will work. The same is true for any file you open without binmode (or I/O layers like :raw). See also binmode.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Thank you for your answers. I just figured out how to save the image (with binmode). But it was only for debugging. The real purpose is to display it in Tk. And still can't make it to work. Here is the whole program:
      use 5.010; use strict; use warnings; use LWP::UserAgent; use Tk; use Tk::PNG; my $url = "https://cdn.keyforgegame.com/media/card_front/en/341_1_7C85 +4VPW72RH_en.png"; my $ua = LWP::UserAgent->new(agent => ''); my $response = $ua->get($url); die $response->status_line if not $response->is_success; my $data = $response->decoded_content(charset => 'none'); my $mw = MainWindow->new; $mw->Photo(-data => $data, -format => 'PNG');
      I have the error 'couldn't recognize image data at ...../perl/vendor/lib/Tk/Image.pm line 21'. Why is that?

        Seems to only work if you base64 encode the binary

        use 5.010; use strict; use warnings; use LWP::UserAgent; use Tk; use Tk::PNG; use MIME::Base64; my $url = 'http://www.perl.com/images/ads/tpcip_banner-1200x150.png'; my $ua = LWP::UserAgent->new(agent => ''); my $response = $ua->get($url); die $response->status_line if not $response->is_success; my $data = MIME::Base64::encode_base64($response->decoded_content()); my $mw = MainWindow->new; my $photo = $mw->Photo(-data => $data, -format => 'PNG'); $mw->Label(-image => $photo)->pack(); MainLoop;
        poj

        Are you sure the image is a PNG? Just because a URL ends in .png, the file does not have to be a PNG. Browsers and image viewers generally accept anything that roughly looks like an image, more or less ignoring file extensions, URL parts, and MIME types.

        Check the first few bytes: They should be 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, according to both Portable_Network_Graphics and http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html.

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: Downloading KeyForge image
by Fletch (Bishop) on May 21, 2019 at 18:57 UTC

    Perhaps enable binmode on STDOUT? You might also check out LWP::Simple which has a getstore routine which writes the contents of an URL into a file for you.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.