http://www.perlmonks.org?node_id=1031701

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

This post is in continuation to wxPerl image handling (short & sweet). and to Steve_BZ's last post there: Re^4: wxPerl image handling (short & sweet)..
Although that thread is 12 years old (and the last post is 3 years old) (they say that good wine only gets better with time), I've found it of interest, and for the benefit of PerlMonks users, I am posting this question, and my experiences.

Steve_BZ: Firstly, I tried to run your script, and it bumps with the same error as that of user "rp{erl}D" in Re^3 above.

I modified your script just a bit, like so:

#!/usr/bin/perl # Taken from: http://permonks.org/?node_id: 794478 use Wx; package MyFrame; # subclass wx::Frame to insert the image control. use vars qw(@ISA); use strict; use Wx qw( wxWidth wxHeight); use IO::File; @ISA=qw(Wx::Frame); sub new { my $class = shift; my $this = $class->SUPER::new( undef, -1, $_[0], $_[1], $_[2] ); # replace the filename with something appropriate. my $file = IO::File->new( # enter a path and image filename of you +r own: 'D:\My Documents\...\IMG_8053.JPG', "r" ) or return undef; binmode $file; # define a handler for jpeg images. my $handler = Wx::JPEGHandler->new(); my $image = Wx::Image->new(); my $bmp; # used to hold the bitmap. $handler->LoadFile( $image, $file ); $bmp=Wx::Bitmap->new( $image ); if( $bmp->Ok() ) { # create a static bitmap called ImageViewer that displays the + selected image. $this->{ImageViewer}= Wx::StaticBitmap->new($this, -1, $bmp); } my $b1 = Wx::LayoutConstraints->new(); $b1->left->Absolute(0); $b1->top->Absolute(0); $b1->width->PercentOf( $this, wxWidth,100); $b1->height->PercentOf( $this, wxHeight, 100); $this->{ImageViewer}->SetConstraints( $b1 ); $this; # return the frame object to the calling application. } 1; package main; my $app = Wx::SimpleApp->new; my $frame = MyFrame->new( "Mini-image demo", [-1,-1], [-1,-1]); unless ($frame) {print "unable to create frame -- exiting."; return +undef} $frame->Show(1); $app->MainLoop; 1;
and then it does run, but:

1. The "constraints" have no effect!
I used an image of size 3200 x 2400 (pretty normal nowadays), and it does not compress or fit it to the frame size, instead it crops the image to the frame window (in other words, if the frame size is, say, 400 x 300, it shows just a sub-region of 400 x 300 pixels out of that image, without compressing or resizing the image).

2. So the bottom line is: what's the right way to display a resizing image in a frame?

3. and even more importantly: how to display an image in a resizing window, under a sub-panel?

Many TIA - Helen

I am using wxWidgets 2.8.12, Wx version 0.9903, StrawberryPerl 5.16 on a WinXP SP3 platform.

  • Comment on wxPerl: how to display a resizing image? (StaticBitmap doesn't seem to work)?
  • Download Code

Replies are listed 'Best First'.
Re: wxPerl: how to display a resizing image? (StaticBitMap doesn't seem to work)?
by Anonymous Monk on May 02, 2013 at 08:14 UTC
Re: wxPerl: how to display a resizing image? (wxImagePanelDemo.pl)
by Anonymous Monk on May 02, 2013 at 23:49 UTC

    perl wxImagePanelDemo.pl
    perl wxImagePanelDemo.pl foo.gif
    #!/usr/bin/perl -- ## http://wiki.wxwidgets.org/An_image_panel use strict; use warnings; Main( @ARGV ); exit( 0 ); sub Main { Wx::InitAllImageHandlers(); my( $file ) = @_; $file ||= Wx::Image->new( Wx::GetWxPerlIcon() )->Scale(240,240); my $frame = Wx::Frame->new( undef, -1, "Hello wxDC", [ 50, 50 ], [ 500, 500 ], ); my $filepane = wIP->new( $frame, $file ); my $iconpane = wIP->new( $frame, Wx::Image->new( Wx::GetWxPerlIcon +() ) ); my $sizer = Wx::BoxSizer->new( Wx::wxVERTICAL() ); my $icon_sizer = Wx::BoxSizer->new( Wx::wxHORIZONTAL() ); for( 1..3){ $icon_sizer->AddSpacer( 30 * $_ ); $icon_sizer->Add( Wx::Button->new( $iconpane, -1, "yo $_" ) ); } $iconpane->SetSizer( $icon_sizer ); $sizer->Add( $filepane, 1, Wx::wxEXPAND() ); $sizer->Add( $iconpane, 1, Wx::wxEXPAND() ); my $pthree = wIP->new( $frame, Wx::Image->new( Wx::GetWxPerlIcon() + ) ); my $pthree_sizer = Wx::BoxSizer->new( Wx::wxHORIZONTAL() ); $pthree_sizer->Add( wIP->new( $pthree, Wx::Image->new( Wx::GetWxPerlIcon() ) )->noscale, ); my $pfunk = wIP->new( $pthree, Wx::Image->new( Wx::GetWxPerlIcon() + ) ); $pthree_sizer->Add( $pfunk, 1, Wx::wxEXPAND(), ); $pthree_sizer->Add( wIP->new( $pthree, Wx::Image->new( Wx::GetWxPerlIcon() ) )->noscale, ); $pthree->SetSizer( $pthree_sizer ); $pthree_sizer->Layout; $pthree_sizer->Show(2); $pthree_sizer->Show(3); $pthree_sizer->Show(4); $sizer->Add( $pthree, 0, Wx::wxEXPAND() ); $frame->SetSizer( $sizer ); $frame->Show(); my $app = Wx::SimpleApp->new; $app->MainLoop; eval { wIP->new(undef,bless[],'purple::hedgehog') ; 1 } or warn $@ +; wIP->new(); ## purple hedgehog } ## end sub Main package wIP; use Wx; use Carp qw/ croak /; use base qw/ Wx::Panel /; sub new { my( $class, $parent, $fileOrImage ) = @_; my $self = $class->SUPER::new( $parent, -1 ); if( ref $fileOrImage ) { $fileOrImage->isa( 'Wx::Image' ) or croak "$fileOrImage not isa Wx::Image"; $self->{image} = $fileOrImage; } elsif( defined $fileOrImage and length $fileOrImage ) { $self->{file} = $fileOrImage; $self->{image} = Wx::Image->new; $self->{image}->LoadFile( $fileOrImage, Wx::wxBITMAP_TYPE_ANY( +), -1 ); } else { croak 'Usage: wIP::new( CLASS, $parent, $filenameOrImage ); '; } $self->{bitmap} = Wx::Bitmap->new( $self->{image} ); $self->{height} = -1; $self->{width} = -1; $self->{transparent} = !! ( $self->{image}->HasAlpha || $self->{image}->HasMask ); Wx::Event::EVT_SIZE( $self, \&wIP::onSize ); Wx::Event::EVT_PAINT( $self, \&wIP::onPaint ); bless $self, $class; return $self; } ## end sub new sub onSize { my( $self, $evt ) = @_; $self->Refresh; $evt->Skip; } sub onPaint { my( $self, $evt ) = @_; my $dc = Wx::PaintDC->new( $self ); my( $n_width, $n_height ) = $dc->GetSizeWH; if( $self->{width} != $n_width or $self->{height} != $n_height ) { unless( $self->{noscale} ){ $self->{bitmap} = Wx::Bitmap->new( $self->{image}->Scale( $n_width, $n_height, ) ); $self->{width} = $n_width; $self->{height} = $n_height; } $dc->DrawBitmap( $self->{bitmap}, 0, 0, $self->{transparent} ) +; } else { $dc->DrawBitmap( $self->{bitmap}, 0, 0, $self->{transparent} ) +; } } sub noscale { my( $self ) = @_; $self->{noscale} = !! 1; $self->SetMinSize( [ $self->{image}->GetWidth, $self->{image}->GetHeight, ] ); return $self; } =head1 NAME wIP - wxImagePanel - display image in a panel, autoscaled or not, back +ground image =head1 METHODS =head2 C<<< new >>> wIP->new( $parent, $filename ); wIP->new( $parent, $filenameOrImage ); wIP->new( $parent, Wx::Image->new( Wx::GetWxPerlIcon() ) ) =head2 C<<< noscale >>> wIP->new( ... )->noscale =cut

      Nice! Works well with the large cosmos.jpg also.

      James

      There's never enough time to do it right, but always enough time to do it over...

      Thank you, AM. This is really virtuoso work.
      Lot to learn.

      Helen

      (By the way, what is the function of the "yo" buttons? When I run the program, they have no effect?)

        By the way, what is the function of the "yo" buttons? When I run the program, they have no effect?

        Yes, the buttons aren't bound to any event handlers

        The purpose is to demonstrate that buttons are drawn ontop of the panelimage, the panelimage is background image, if you resize the frame/window, the background image should resize, but the buttons wouldn't resize, and you should see the buttons remain ontop of the panelimage