Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

PerlMagick Gtk2::Gdk::Pixbuf

by renegadex (Beadle)
on Jul 21, 2008 at 05:07 UTC ( [id://698981]=perlquestion: print w/replies, xml ) Need Help??

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

Hi! i have this code:
use Gtk2 '-init'; use Image::Magick; my $magick = Image::Magick->new; $magick->Read('pictures/ian.jpg'); $magick->Set(magick=>'xpm'); my $blob = $magick->ImageToBlob(); $pixbuf = Gtk2::Gdk::Pixbuf->new_from_xpm_data ($blob); i get this error: GdkPixbuf-WARNING **: Inline XPM data is broken: Invalid XPM header at + tk-photo.pl line 9.
i want to put the picture loaded by imagemagick into memory, then the memory is read by a gdk pixbuf. also, if my picture is big (2000x2000 pixels) i think it would be very slow to convert it into xpm format... any other ideas to get image data from image magick using gdk pixbuf without writing to disk. tnx!

Replies are listed 'Best First'.
Re: PerlMagick Gtk2::Gdk::Pixbuf
by snoopy (Curate) on Jul 21, 2008 at 06:16 UTC
    I've noticed this recent bug fix to the XS binding for the new_from_xpm_data function.

    If you haven't already, it might help to try this against the latest Gtk 1.183.

Re: PerlMagick Gtk2::Gdk::Pixbuf
by zentara (Archbishop) on Jul 21, 2008 at 14:01 UTC
    You don't need to convert to the xpm format, the pixbuf-loader will auto-detect a wide variety of image types and load them into a pixbuf. Here is a simple example, (I don't use IM, but it is essentially the same data from a scalar), the base64encoded image is a small jpg.
    #!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; use MIME::Base64; my $window = Gtk2::Window->new('toplevel'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_default_size(500,430); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); $hbox->set_size_request(500,48); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); my $button1 = Gtk2::Button->new('Set BG'); $hbox->pack_end( $button1, FALSE, FALSE, 0 ); $button1->signal_connect( clicked => \&set_bg); my $vbox1 = Gtk2::VBox->new( 0, 5 ); $vbox->pack_end ($vbox1, TRUE, TRUE, 0); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; } ############################################################### sub set_bg{ #print "@_\n"; # get the blob, I didn't use IM here, but it comes from # a scalar my $bunny = get_bunny(); # crude method #my $pixbufloader = Gtk2::Gdk::PixbufLoader->new; #my $raw_data = `cat ./bridget-1.jpg`; #$pixbufloader->write($raw_data); #$pixbufloader->close; #my $pixbuf = $pixbufloader->get_pixbuf; # preferred method # this properly renders it, save this do statement for future use :-) my $pixbuf = do { my $loader = Gtk2::Gdk::PixbufLoader->new(); $loader->write( $bunny ); $loader->close(); $loader->get_pixbuf(); }; # get dimensions if desired my ($x, $y) = ($pixbuf->get_width, $pixbuf->get_height); #print "$x $y\n"; #print 'rowstride->', $pixbuf->get_rowstride,"\n"; #set the new pixbuff in the window # make image my $img = Gtk2::Image->new_from_pixbuf($pixbuf); $vbox1->pack_start($img,FALSE,FALSE,0); $img->show(); #return FALSE; } ################################################################# sub get_bunny{ return decode_base64( 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAjCAYAAACD1LrRAAAABmJLR0QA/wD/AP+gvaeTA +AAACXBI WXMAAAsSAAALEgHS3X78AAAAmElEQVRYw+1WQQ7AIAizxP9/mV121Gm0BZfYxNukKxSwlI +Pg75HG MrGALkykfHjPBKmf+tbIAad/0Ngp3CHGIrnvEoco7xFDTf6lGMIeH6YaBNVYrTEUKYfYUG +DW0bOI t2qrTjVYNXa2f9SDAqt97I1AlMFST9pOIbjEYRuKsSS4fUZydcqSQOTzVubq/w+QmmVWtm +IvFx08 tNghLUXwK/sAAAAASUVORK5CYII='); }
    The formats that are handled by your GTk2 libs can be found with
    #!/usr/bin/perl use strict; use warnings; use Gtk2; my @formats = Gtk2::Gdk::Pixbuf->get_formats(); my @exts; foreach my $format ( @formats ) { foreach my $key ( keys( %$format ) ) { next unless $key eq 'extensions'; foreach my $elem ( @{ $format->{ $key } } ) { push @exts, $elem; } } } print "@exts\n";

    I'm not really a human, but I play one on earth Remember How Lucky You Are
      wow! thanks zentara! that worked for me! thanks again! how come you know a lot? are you working for some kind of image processing software or company? im very impressed!
        Well it was confusing for me at first too. I subscribe to the Perl/Gtk2 maillist and asked alot of questions, and ran alot of example code found in their archives. You can download their archives in monthly chunks, and search them for code. muppet in particular has been very helpful explaining the difficult parts of Gtk2. The do statement to use the pixbuf-loader was put on the maillist by Aristotle.

        If you are getting into Perl/Gtk2, start getting in the habit of opening the perldoc for whatever widget you are interested in, and look at the top, where the inheritance is shown, and at the bottom where the signals are shown. Most of the tougher problems require you to use an inherited method on the widget, or some clever juggling of the events and signals available to that widget.

        Also check out the nice studyguide at novell perl gtk2 studyguide


        I'm not really a human, but I play one on earth Remember How Lucky You Are
        zentara knows where to find documentation and read it, and does so frequently :)
      i would like to share the program that i did. its messy but you can see how i did what zentara showed us.
      #!/usr/bin/perl -w #image data transfer from imagemagick to pixbuf!!! yey! use Gtk2 '-init'; use Image::Magick; my $pimage; my $pimage2; my $image; my $image2; my $canvas; my $pixbufloader; my $pixbuf; #sub load; my $window = Gtk2::Window->new; $window->signal_connect(destroy=>sub{Gtk2->main_quit;}); $window->set_size_request(1000,600); my $vbox = Gtk2::VBox->new; $window->add($vbox); #my $pixbuf = Gtk2::Gdk::Pixbuf->new(undef); our $image1 = Gtk2::Image->new; my $swin = Gtk2::ScrolledWindow->new; $swin->add_with_viewport($image1); $vbox->pack_start($swin,1,1,0); my $button = Gtk2::Button->new('LOAD'); $button->signal_connect('clicked',\&load); $vbox->pack_start($button,0,1,0); my $button1 = Gtk2::Button->new('VIEW'); $button1->signal_connect('clicked',\&view); $vbox->pack_start($button1,0,1,0); my $button2 = Gtk2::Button->new('IMPLODE'); $button2->signal_connect('clicked',\&implodeimage); $vbox->pack_start($button2,0,1,0); $window->show_all; Gtk2->main; sub load { $image = Image::Magick->new; $image2 = Image::Magick->new; $pimage = Image::Magick->new; $pimage2 = Image::Magick->new; $pimage->Read('frames/rbs5r.png'); $pimage2->Read('pictures/dscf6098.jpg'); $image = $pimage->Clone; $image2 = $pimage2->Clone; $image->Resize( height=>650, width=>(650*$image->Get('width')/$image->Get('height'))); $image2->Resize( height=>650, width=>(650*$image2->Get('width')/$image2->Get('height'))); $canvas = Image::Magick->new; my $w = $image->Get('width'); my $h = $image->Get('height'); my $size = $w . "x" . $h; $canvas->Set(size=>$size); $canvas->ReadImage('xc:white'); $canvas->Set(magick=>'jpeg'); $canvas->Composite( image=>$image2, compose=>'Over'); $canvas->Composite( image=>$image, compose=>'Over'); my $blob = $canvas->ImageToBlob(); $pixbufloader = Gtk2::Gdk::PixbufLoader->new; $pixbufloader->write($blob); $pixbufloader->close; $pixbuf = $pixbufloader->get_pixbuf; $blob = $pixbuf->save_to_buffer('jpeg'); $canvas->BlobToImage($blob); $canvas->Display; #my $preview = $image->Preview('Gamma'); #$preview->Display(); } sub view { #$pixbuf = Gtk2::Gdk::Pixbuf->new_from_file('text.bmp'); $image1->set_from_pixbuf($pixbuf); } sub implodeimage { print "IMPLODE\n"; # print $image2->Blur(20); #$canvas=$image->Clone; $canvas = Image::Magick->new; my $w = $image->Get('width'); my $h = $image->Get('height'); my $size = $w . "x" . $h; $canvas->Set(size=>$size); $canvas->ReadImage('xc:white'); #$image->Crop(geometry=>$size); #$image2->Crop(geometry=>$size); #$image2->Rotate(45); print $canvas->Composite(image=>$image2,compose=>'Over'); print $canvas->Composite(image=>$image,compose=>'Over'); print $canvas->Write('text.bmp'); }
      you can try this out. first change the image files inside the SUB LOAD. run the program and press the LOAD BUTTON. the sub LOAD does the following... open a file using image magick. do something to it then convert it to a blob. then the blob is read by the pixbufloader and is then converted into a pixbuf! yey! then the pixbuf is then converted to a blob. which is then read by image magick!!!! yey!!!!
        A couple of comments. First your use of the word canvas for a ImageMagick object is slightly confusing, but it's legal. Second, I know it's just a preliminary example, but if you are going to make it into an app that will load many pictures and operate on them, you should make your IM objects global and reuse them, so you are not making new ones all the time. You can clear out an IM object with
        #reuse object undef @$IMagick_object; # clear out IM object data

        I'm not really a human, but I play one on earth Remember How Lucky You Are
Re: PerlMagick Gtk2::Gdk::Pixbuf
by Anonymous Monk on Jul 21, 2008 at 14:09 UTC
    You should look into Gtk2::Gdk::PixbufLoader, it allows you to load jpg/png/gif/... data to create a pixbuf.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://698981]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (1)
As of 2024-04-19 00:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found