Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

What's wrong with this Wx::Bitmap construction?

by isync (Hermit)
on Feb 25, 2010 at 18:47 UTC ( #825365=perlquestion: print w/replies, xml ) Need Help??

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

I am feeding a Wx::ListCtrl with an image list and use the following code to read images in from file:
my $images_sm = Wx::ImageList->new( 16, 16, 1 ); $images_sm->Add( Wx::Bitmap->new("bin/icons/$_.gif", wxBITMAP_TYPE_GIF +) );
This works.
Now, moving the image data into a module and reading in the data from a string fails, why?
use MIME::Base64 (); $raw_data = "R0lGODlhEAAQAJEAAAAAAP///+vc3AAAACwAAAAAEAAQAAACDpSPqcvtD +6OctNqLsz4FADs="; my $icon_data = MIME::Base64::decode_base64( $raw_data ); my $images_sm = Wx::ImageList->new( 16, 16, 1 ); my $file = IO::Scalar->new( \$icon_data ); my $image = Wx::Image->new(); $image->LoadFile( $file, wxBITMAP_TYPE_ANY ); close($file); $images_sm->Add( Wx::Bitmap->new($image, -1) );
I hope I did not infuse an error while copy&paste'ing the simplified code...

Replies are listed 'Best First'.
Re: What's wrong with this Wx::Bitmap construction?
by almut (Canon) on Feb 25, 2010 at 20:57 UTC

    Are you sure that $image->LoadFile(...) can take an IO::Scalar object?

    Maybe try instead

    open ICON, '<', \$icon_data or die $!; ... $image->LoadFile( \*ICON, wxBITMAP_TYPE_ANY );

    (lexical file handles might be ok, too — the ->LoadFile( \*FH, ...) syntax is just gleaned from one of the test files that come with Wx)

      So, I've tried your proposal:
      open ICON, '<', \$icon_data or die $!; my $image = Wx::Image->new(); $image->LoadFile( \*ICON, wxBITMAP_TYPE_ANY ); $images_sm->Add( Wx::Bitmap->new($image, -1) );
      The result were errors like this: "Can't load image from file 'Wx::Image=SCALAR(0x33094dc)': file does not exist. Couldn't add an image to the image list."

      Are you sure that $image->LoadFile(...) can take an IO::Scalar object?
      No, I am not. I just adapted this trick from videobox (sorry, there is no browsable CVS there, you need to look into the released .zip, in dir VBR/, this app's resource lib), where it sais:
      package VBR::RES; # WARNING This file was automatically created by # Any changes will be lost! use MIME::Base64; use FindBin; use Carp; my %res=(); # Toolbar button bitmaps must be 16x15 256 colors! sub GetResource { my($name)=@_; $resname=lc($name); $resname =~ s/\\/\//g; if (defined $res{$resname}) { return $res{$resname}; } else { open(FILE,"$FindBin::RealBin/$name") or die $!; binmode(FILE); my $data=join('',<FILE>); warn("Read ".length($data)." bytes from file: $FindBin::RealBi +n/$name\n"); return $data; } } sub OpenResource { my($name)=@_; use IO::Scalar; my $data = GetResource($name); return IO::Scalar->new( \$data ); } sub GetImage { my($name)=@_; use Wx qw( wxBITMAP_TYPE_BMP ); my $file = OpenResource($name); my $image = Wx::Image->new(); $image->LoadFile( $file, wxBITMAP_TYPE_BMP ); close($file); return $image; } sub GetBitmap { my($name)=@_; return Wx::Bitmap->new(GetImage($name)); } Wx::InitAllImageHandlers(); my $resname=''; while (<DATA>) { if (/^$/) { undef $resname; } elsif (/^@(.*)/) { $resname=lc($1); $resname =~ s/\\/\//g; } elsif ($resname) { $res{$resname}.=decode_base64($_); } } close(DATA); 1; __DATA__ @vbr/bitmaps/add.bmp Qk0mBQAAAAAAADYEAAAoAAAAEAAAAA8AAAABAAgAAAAAAPAAAAASCwAAEgsAAAAAAAAAAA +AAAAAA AAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAAgQAAAIGAAACCAAAAgoA +AAIMAA ACDgAABAAAAAQCAAAEBAAABAYAAAQIAAAECgAABAwAAAQOAAAGAAAABgIAAAYEAAAGBgAA +BggAAA YKAAAGDAAABg4AAAgAAAAIAgAACAQAAAgGAAAICAAACAoAAAgMAAAIDgAACgAAAAoCAAAK +BAAACg YAAAoIAAAKCgAACgwAAAoOAAAMAAAADAIAAAwEAAAMBgAADAgAAAwKAAAMDAAADA4AAA4A +AAAOAg AADgQAAA4GAAAOCAAADgoAAA4MAAAODgAEAAAABAACAAQABAAEAAYABAAIAAQACgAEAAwA +BAAOAA QCAAAEAgIABAIEAAQCBgAEAggABAIKAAQCDAAEAg4ABAQAAAQEAgAEBAQABAQGAAQECAAE +BAoABA QMAAQEDgAEBgAABAYCAAQGBAAEBgYABAYIAAQGCgAEBgwABAYOAAQIAAAECAIABAgEAAQI +BgAECA gABAgKAAQIDAAECA4ABAoAAAQKAgAECgQABAoGAAQKCAAECgoABAoMAAQKDgAEDAAABAwC +AAQMBA AEDAYABAwIAAQMCgAEDAwABAwOAAQOAAAEDgIABA4EAAQOBgAEDggABA4KAAQODAAEDg4A +CAAAAA gAAgAIAAQACAAGAAgACAAIAAoACAAMAAgADgAIAgAACAICAAgCBAAIAgYACAIIAAgCCgAI +AgwACA IOAAgEAAAIBAIACAQEAAgEBgAIBAgACAQKAAgEDAAIBA4ACAYAAAgGAgAIBgQACAYGAAgG +CAAIBg oACAYMAAgGDgAICAAACAgCAAgIBAAICAYACAgIAAgICgAICAwACAgOAAgKAAAICgIACAoE +AAgKBg AICggACAoKAAgKDAAICg4ACAwAAAgMAgAIDAQACAwGAAgMCAAIDAoACAwMAAgMDgAIDgAA +CA4CAA gOBAAIDgYACA4IAAgOCgAIDgwACA4OAAwAAAAMAAIADAAEAAwABgAMAAgADAAKAAwADAAM +AA4ADA IAAAwCAgAMAgQADAIGAAwCCAAMAgoADAIMAAwCDgAMBAAADAQCAAwEBAAMBAYADAQIAAwE +CgAMBA wADAQOAAwGAAAMBgIADAYEAAwGBgAMBggADAYKAAwGDAAMBg4ADAgAAAwIAgAMCAQADAgG +AAwICA AMCAoADAgMAAwIDgAMCgAADAoCAAwKBAAMCgYADAoIAAwKCgAMCgwADAoOAAwMAAAMDAIA +DAwEAA wMBgAMDAgADAwKAA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AA +cHBwcH BwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcAAAAAAAcHBwcHBwcHBwcAAPn5+Q +AABwcH BwcHBwcA+fn5+fn5+QAHBwcHBwcHAPn5+QD5+fkABwcHBwcHAPn5+fkA+fn5+QAHBwcHBw +D5+QAA AAAA+fkABwcHBwcA+fn5+QD5+fn5AAcHBwcHBwD5+fkA+fn5AAcHBwcHBwcA+fn5+fn5+Q +AHBwcH BwcHBwAA+fn5AAAHBwcHBwcHBwcHBwAAAAcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBw +cHBwcH BwcHBwcHBw== (snip)

      Is there some magic in VBR/'s routine nesting? And: the maturity of the videobox app tells me there must be some nasty bug in my routine... Anyone objecting?
Re: What's wrong with this Wx::Bitmap construction?
by Anonymous Monk on Feb 26, 2010 at 07:39 UTC
    Now, moving the image data into a module and reading in the data from a string fails, why?

    How does it fail? What error do you get?

      Actually, it just silently doesn't work. No errors, but the images do not show up in my ListCtrl.
      Wrong memory. A new try showed that it produces the same error as above, the "Can't load image from file 'Wx::Image=SCALAR(0x33094dc)': file does not exist." error.
      (BTW: is this the Wx::Image or Wx::Bitmap constructor failing?)
        Why not create a self contained example which demonstrates your problem?
Re: What's wrong with this Wx::Bitmap construction?
by isync (Hermit) on Mar 03, 2010 at 11:34 UTC
    Thank you Anonymous Monk! I am now able to create a Wx::Bitmap from XPM data. Using the newFromXPM constructor, and passing it array-refs. Contrary to newFromBits, newFromXPM expext ( $dat-array-ref ) only and not ( $data, sizeX, sizeY ) as FromBits. I use Wx itself to convert the gifs via a simple utility script and write a, for anyone interested (some magic excluded..):
    Wx::InitAllImageHandlers(); my $bmp = Wx::Bitmap->new("$_", wxBITMAP_TYPE_GIF); my $ok = $bmp->SaveFile("$fname.xpm", wxBITMAP_TYPE_XPM); open(my $dat, "$fname.xpm") || die("Could not open file! $fname.xp +m $!"); my @raw_data=<$dat>; close($dat); my @filtered; for(@raw_data){ next if $_ =~ /^\/\*/; next if $_ =~ /^static/; next if $_ =~ /^\}/; $_ =~ s/\@/\\@/g; $_ =~ s/\$/\\\$/g; $_ =~ s/\&/\\&/g; $_ =~ s/\%/\\%/g; push(@filtered,$_); } my $data = join('',@filtered); $vars .= "\$images->{$fname}\t= [". $data ."];\n\n";

    A working example of a script using this approach can be found on this blog post: WxPerl: Converting images for use as embedded XPM in your Perl code

    BTW: Am I the only one who has another password since the break-in, forgets about it, and when posting after a fast login notices *after* posting that he/she has posted as anonymous... (Happened on this thread when I provided the working example...) ;)
Re: What's wrong with this Wx::Bitmap construction?
by stefbv (Curate) on Jun 27, 2010 at 15:29 UTC

    What's wrong? Nothing. :)

    Here is a working example (at least on my system), of an embedded icon. The icon data is from the tkIcons file, part of the Tk::ToolBar module.

    Regards, Stefan

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://825365]
Front-paged by keszler
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2023-03-24 18:57 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (61 votes). Check out past polls.