in reply to Tk:Photo -data with binary data?

Not certain if you really mean binary data, my understanding is Tk::Photo wants Base64 data, so you just need to run your binary image data thru MIME::Base64::encode_base64() and supply that output to Tk::Photo(-data).

Or use the handy bintoscalar utility...

Replies are listed 'Best First'.
Re^2: Tk:Photo -data with binary data?
by BrowserUk (Patriarch) on Nov 28, 2006 at 21:26 UTC

    I actually do mean binary data, per the Tk::Photo docs:

    -data => string

    Specifies the contents of the image as a string. The string can contain base64 encoded data or binary data.

    I have the image data in memory, and wish to avoid either writing it to a file or converting it to base64.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Well, it will very much depend on the image format of the data (eg. "gif", or "jpg", or "png", or whatever).  Tk only supports certain image formats:
      IMAGE FORMATS The photo image code is structured to allow handlers for additiona +l image file formats to be added easily. The photo image code mainta +ins a list of these handlers. Handlers are added to the list by register +ing them with a call to Tk_CreatePhotoImageFormat. The standard Tk distribution comes with handlers for XBM, XPM, BMP, JPEG, PNG and PPM/PGM formats, which are automatically registered on initializat +ion.

      and in the next paragraph ...

      Usually this will find the correct handler, but if it doesn't, the user may give a format name with the -format option to specify which handler to use.

      I'm assuming you know what the image format is of the image you have in memory.  Why not just try displaying the image yourself?  As the Tk documentation illustrates, you can use:

      my $img = $mw->Photo(-data => $data);

      and if necessary supply -format => FORMAT (for one of the valid IMAGE FORMATS above).

      Have you tried doing that yet?


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

        Yes, I've tried that too. The following example works if you switch the comment cards to encode the data base64, but not without. I've also tried various different formats that GD support (.jpg, .gif). The result is always couldn't recognize image data at c:/Perl/site/lib/Tk/Image.pm line 21, which is annoying because it can read that same data back from a file, with or without a format hint.

        It seems strange that is can read the data from a file, but not directly from memory. If the -file option would take a file handle instead of a name, I could throw the data into a ramfile, but it doesn't :(

        The time taken to convert the image to base64 to pass it into tk--where it is presumably converted straight back again--thrashes the cpu to death and really slows things down of you are trying to update the image quickly.

        #! perl -slw use strict; use Tk; use Tk::PNG; use GD::Graph; use GD::Graph::bars; use MIME::Base64 qw[ encode_base64 ]; my $data = [ [qw/1st 2nd 3rd 4th 5th 6th 7th 8th 9th/], [qw/ 1 2 5 6 3 1.5 1 3 4/], ]; my $graph = GD::Graph::bars->new(400, 300); $graph->set( x_label => 'X Label', y_label => 'Y label', title => 'Some simple graph', y_max_value => 8, y_tick_number => 8, y_label_skip => 2 ) or die $!; my $gd = $graph->plot($data) or die $!; my $mw = MainWindow->new; my $png = $mw->Photo( # -data => encode_base64( $gd->png ), -data => $gd->png, -format => 'png' ); my $btn = $mw->Button( -text => 'doit', -command => sub{ $data->[ 1 ] = [ map{ rand 5 } 1 .. 9 ]; undef $graph; $graph = GD::Graph::bars->new(400, 300); $graph->set( x_label => 'X Label', y_label => 'Y label', title => 'Some simple graph', y_max_value => 8, y_tick_number => 8, y_label_skip => 2 ) or die $!; my $gd = $graph->plot($data) or die $!; $png->blank; $png->configure( # -data => encode_base64( $gd->png ), -data => $gd->png, -format => 'png' ); $mw->update; } )->pack; $mw->Label(-image => $png)->pack; $mw->repeat( 1000, sub{ $btn->invoke; $png->update } ); MainLoop; __END__ couldn't recognize image data at c:/Perl/site/lib/Tk/Image.pm line 21.

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

      Dunno, the following example should work but it doesn't. It seems that some formats can't read data from strings, for whatever reasons. This is somewhat hinted in the docs:

      data => string
      Specifies the contents of the image as a string. The string can contain base64 encoded data or binary data. The format of the string must be one of those for which there is an image file format handler that will accept string data. If both the -data and -file options are specified, the -file option takes precedence.
      #!/usr/bin/perl use strict; use warnings; use Tk; use Tk::Photo; use Tk::PNG; my $fdata = pack 'H*', join '', map {chomp;$_} <DATA>; my $mw = new MainWindow(); $mw->Label(-image => $mw->Photo(-format => 'png', -data => $fdata))->p +ack; MainLoop; __DATA__ 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000 000473424954080808087c0864880000031149444154388d5d934b685c6518869fff9c b9672699c4244c27186348a6dad462e9c6120af5428ba274a1502b144a45501071ab2e 155d195ce842d4950bc18d2e24daaad5452b4a3596c4b69a26c44e636e93c964a69999 73ce7ff95cc496c667f52ebef785efa6b88391936799fbf408c327bece88b5bb9c369d 36d4b848d79cb1ab2b3f9e6cf33fd42d513a7d0e7192146bc7ad754f86b1cc01a36205 17196836ca5e6d63c606c1e71877b1fafb8b764740e9f97388901291d75c22737a78cf 60f1c8de9cb7a7dfc747b8bcacf961aa2217cffc36afab1befdb407fd4987db505a046 4f7d87f2bdac08efe4ef2ebe7cfcd17b38ba3b45dc87283224123ea0700267671a7cfc e179ca53b36f99adf69bade5d7230f4f7962dd31c9e64f1c7b7898bdc524cb5bc2b595 90563324080c4b75433d84fb073b79eed438b942ef0bce98c7003cb1aea0bdf8332363 433ddd1d71166ac2f5d536439d96fd436976f7f9ec2f28c6fa84f99a90e9e9a274f460 9f75f26cace38d6c4c8cbd5765b3877abbd3aa5cb30c77043c7e5f9c819ec4ed49a712 a0adb0d1b44c2e785ca3df733dfd07a4fcf788e7b4c978e9f45d952881d2214fef4b52 ec8edf368b0800314ff144c92712a89804b650ec126db231ab0d8186b94d8525cdf4ba e250069a214caf81b68e870a8e6432cee5aaa2d252dbcbf36288133cd1c64537db6669 d3706151f1cd3c680b5b11fcba04d34b42181aacc057b370bd0668039bb508d09ed366 9dc6e6acde0a080221d2020802e0605bfcd78e0565049a81b078e306b016b391998bad 2e4ee672bda3aab42fbe50b55c287b8416ca0d505631b5e2c106fc59817cdcd29cfa29 8aaa956f81b202e83bf8c998f8c9cf3ac60f3f901e18209f024f413ddc3ed57c0a222b d4db42fdd28c54bef8f2175b6f1c8789b20f90293eb56e5bed69b3f4cf239938d9743e e7c51331b20945260e38836bb5d83cffb3ae9cf9fe0f536fbc84bc7b75c7337595dec3 19fb20c82bf9c181c35d83c5a154ae433963a455addb8db97279edd2d549e003e02f98 901d01b7c8ec7abbc7467ad4467accf7fda26907ce867a71dbc41598b87967fdbffa74 99fc896501e90000000049454e44ae426082

      It dies with the error:

      couldn't recognize image data at /usr/lib/perl5/Tk/Image.pm line 21, < +DATA> line 25.

      If I dump $fdata to a file and then use -file => ..., it works.

        Yes. That's the same results I am getting. See Re^4: Tk:Photo -data with binary data?.

        It seems strange that there would have to be special handling for binary data from a string, when it can handle that same binary data froma file. It should only need to detect the presence of non-base64 characters in the data supplied?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.