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

I just found an old program that I wrote a while ago (with help from zentara, I believe). The program initially loaded an 8 bit geotiff but I would like to use the USGS Seamless maps, which are 32 bit. When I go to try and load it I get this:
Failed to load image 'NED_52181266.tif': Failed to load RGB data from +TIFF file: Sorry, can not handle images with 32-bit samples at goo2.1.pl line 64.
Which is the line:my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file ($filename);. So since it has been awhile, curiosity struck me in wondering if there has been any improvements. IOWs is there any way to display these geotiffs?

For good measure heres the code:

#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 -init; use Goo::Canvas; use Image::ExifTool; use Geo::Coordinates::UTM; #use Geo::ShapeFile; #variables my $ellipsoid = 23; #static WSG83 my $zone; my @mtp; my @ps; my @cs; my $count = 1; #my %waypoints = (); #my @drop; #my @points; my $way_ref = []; #my $shape_ref = []; #GeoTiff Info my $filename = 'NED_52181266.tif'; my $exifTool = new Image::ExifTool; my $info = $exifTool->ImageInfo($filename); foreach (sort keys %$info) { print "$_ => $$info{$_}\n"; #Find the right keys(data) if ($_ eq "ModelTiePoint"){ @mtp = split(/ /,$$info{$_}); } if ($_ eq "PixelScale"){ @ps = split(/ /,$$info{$_}); } if ($_ eq "ProjectedCSType"){ @cs = split(/ /,$$info{$_}); $zone = $cs[3]; } } #Create Window my $window = new Gtk2::Window ( "toplevel" ); $window->signal_connect ("delete_event", sub { Gtk2->main_quit; }); $window->set_border_width (10); $window->set_size_request(640,480); $window->set_position('center'); #Create Scrolled Window my $scwin = Gtk2::ScrolledWindow->new(); $scwin->set_policy('always','always'); $window->add($scwin); #add canvas my $canvas = Goo::Canvas->new(); $scwin->add($canvas); my $root = $canvas->get_root_item(); #waypoint lines group my $way_group = Goo::Canvas::Group->new($root); #add Background image my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file ($filename); my $image = Goo::Canvas::Image->new($root, $pixbuf, 0, 0, 'width' => $pixbuf->get_width, 'height' => $pixbuf->get_height); #fills the canvas with the image; default(0,0,1000,1000) #$canvas->set_bounds(0, 0, $pixbuf->get_width, $pixbuf->get_height); #handle the events $canvas->signal_connect (event => \&event_handler); #Start the waypoint connector my $points = Goo::Canvas::Points->new($way_ref); my $way_lines = Goo::Canvas::Polyline->new($root,TRUE,undef, stroke_color => 'black', line_width => 3); $way_lines->set(points => $points); $window->show_all; Gtk2->main; #------------------------------------------------ #handle the mouse events sub event_handler { my ( $widget, $event ) = @_; #on 2 mouse presses if ( $event->type eq "2button-press" ) { my ($x,$y) = ($event->x,$event->y); print 'x->',$x,' ','y->',$y; #convert UTM to Lat and Long my $easting = $ps[0] * $x + 0.0 * $y + $mtp[3]; my $northing = (-$ps[1]) * $y + 0.0 * $x + $mtp[4]; my ($latitude,$longitude)=utm_to_latlon($ellipsoid,$zone,$east +ing,$northing); print " ($latitude, $longitude)"; #Drop waypoint icon my $tgroup = Goo::Canvas::Group->new ($root); Goo::Canvas::Ellipse->new($tgroup,$x,$y,7.5,7.5, fill_color => 'purple', stroke_color => 'black'); Goo::Canvas::Text->new ($tgroup,$count,$x,$y,-1,'GTK_ANCHOR_CE +NTER', font => 'Sans Bold 15', fill_color => 'pink', ); print " $count\n"; push @$way_ref,$x,$y; my $points = Goo::Canvas::Points->new($way_ref); $way_lines->set(points => $points); $count++; print "$way_ref\n"; return; } #remove waypoints if ($event->type eq "button-press" && $event->button == 3){ my ($x,$y) = ($event->x,$event->y); print "right click\n"; my $items = $canvas->get_item_at($x,$y,TRUE); my $parent = $items->get_parent; print "$parent\n"; print $items->get_bounds,"\n"; $parent->remove; [\@points]); } #------------------------------------------------

Replies are listed 'Best First'.
Re: 32 bit images using Pixbuf
by zentara (Cardinal) on Mar 06, 2009 at 11:28 UTC
    You might want to ask this on the Perl/Gtk2 maillist. IIRC, the Gtk2 pixbufs are limited to 24 bits data. Also there may be some clever bit-shift( which I'm unaware of) that will convert the 32 to 24 bit, for loading. From my notes:
    $pixbuf = Gtk2::Gdk::Pixbuf->new_from_data ($pixels, # packed image data in a scalar 'rgb', # only 24- or 32-bit RGB are supported 0, # no alpha, data is 24-bit 8, # only 8 bits per sample are supported $w, # in pixels $h, # in pixels $w*3); # number of *bytes* in each row

    I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
Re: 32 bit images using Pixbuf
by zentara (Cardinal) on Mar 08, 2009 at 18:46 UTC
    I mentioned earlier, about a bit-shift method to convert from 32 to 24 bit. Now.... I don't know if this is the right method, but you might want to closely read the following from the Gtk2 maillist. There MAY be a way to bit-shift, instead of resorting to Image::Magic or GD, Imager,etc. to convert from 32 to 24 bit color.

    I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
      Thanks for the reply. I gave it a try and got an image. Though the image was crazy looking. Not sure if it is better to keep hunting for a way to resample, or find a source for geotiffs that are samplable, or to just load the window with a set of bounds.
        Well, the bit shift in the reply above, was designed to convert color to black and white, or some sort of greyscale manipulation, IIRC ; like I said, I didn't have the time to really dig into what muppet was saying in:
        $data = pack "C*", map { $_ >> 8 } unpack "S*", $raw;
        However, there MAY be a way to modify the map, to selectively remove the high (or low) 8 bits of the image, to convert down to 24 bit from 32 bit. It may be a simple as changing the shift to
        $data = pack "C*", map { $_ << 8 } unpack "S*", $raw; # >> to <<
        or you may need to break the geotiff bits into r g b segments, and bit shift each segment the proper amount and direction. ???

        It may be worth posting the above map as a new node, and asking the c and bit experts if they see a way. It would help if you could describe exactly the bit-field structure of the 32-bit geotiffs that you are dealing with. This is actually a very interesting question.


        I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness
Re: 32 bit images using Pixbuf
by tonyc (Hermit) on Apr 06, 2009 at 00:20 UTC

    The error here is complaining about 32-bit samples, so you don't need to lose 8 bits of data, but 24.

    You need to use some tool that understands 32-bit sample TIFFs - eg. Imagemagick, Imager and use that to convert to 8 bit samples.

    eg.

    convert input.tif -depth 8 output.tiff

    or

    use Imager; my $im = Imager->new; $im->read(file => "input.tif") or die $im->errstr; my $im8 = $im->to_rgb8; $im8->write(file => "output.tif") or die $im->errstr;
Re: 32 bit images using Pixbuf
by Anonymous Monk on Mar 06, 2009 at 10:40 UTC
    So since it has been awhile, curiosity struck me in wondering if there has been any improvements. IOWs is there any way to display these geotiffs?
    Any solution is going to depend on the library which gave you that error message (pixbuff, libtiff...), so I think you're better off asking their developers.

    IOWs is there any way to display these geotiffs?
    Try converting them, re-sampling ...