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

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

I've been asking a few questions regarding Tk lately, and once again, this has to do with Tk.

I have a lot of GIF images, and they all are displayed as buttons. To view them in a matrix of 4x4, they are all resized to a certain $MAX_HEIGHT and $MAX_WIDTH like this:
$images[$y] = $mainframe->Photo(-file => "$file.gif"); my ($height, $width) = ($images[$y]->height, $images[$y]->widt +h); my $yfactor = $height/$MAX_HEIGHT; my $xfactor = $width/$MAX_WIDTH; my $scalefactor = $xfactor > $yfactor ? int($xfactor) : int($y +factor); $scalefactor +=1; my $scaledimage = $mainframe->Photo("button$y"); $scaledimage->copy($images[$y], -subsample => $scalefactor); $images[$y]->destroy();
this snippet of code is executed within a loop (that's why the @images exists)...

The problem I have is that I actually want all images to have the exact same width. With this code (using $scaledimage->copy($images[$y], -subsample => $scalefactor) it's only possible to use integers as $scalefactor.
I know I can use PerlMagick to resize images, save them and reload them again, but that takes two more disk-actions, and the whole thing isn't that fast already.

Is is possible to scale an image in Tk with 'floats' ? Rescaling with integers makes images either large or small...

Jouke Visser, Perl 'Adept'

Replies are listed 'Best First'.
(ichimunki) re: Resizing images && Tk
by ichimunki (Priest) on Mar 14, 2001 at 03:42 UTC
    Since your code above looks a lot like something I did, I should point out the resize routine in my pic thresher application. You won't find any improvements to the resizing bit, but you may find it helpful in other ways.

    My cursory tests indicate that the subsample argument is an integer deal. It seems it literally plucks out every nth pixel. There is a 'zoom' option in the $Photo->copy() method, which you might use to first enlarge the image, then shrink it back down. For instance, to get to 67% image size, you would zoom by 2 then subsample by 3. For 75%, zoom by 3, then subsample by 4. I've never had the urge to try this, as it seems like a guarantee for some ugly images. {grin} (not to mention the mental agony required to make a table of all these zoom/subsample ratios).

    Tk::Photo also has a $Photo->get(x, y) method, which you could use to grab information about specific sets of pixels, then create new smaller sets of pixels from. So to get a 75% reduction grab a 4x4 "cell" from the image, then use your favorite algebraic formulas to compute corresponding values for a 3x3 "cell". Iterate until you have run out of cells. I'm guessing that using any of the other graphics modules would be more fun than this-- tempting as I'm sure the exercise sounds. Suggested module: GD.
Re: Resizing images && Tk
by archon (Monk) on Mar 14, 2001 at 03:39 UTC
    I don't have Tk or GD available to me at the moment, so I'm just theorizing, but...

    Could you make the image a GD object and then use that as the -data for your Tk::Photo? Then you could maybe use GD to manipulate the image (GD::Image::copyResized).

    I know it's not exactly what you were looking for, but I don't see any way to scale a Tk::Photo in non-integer steps. The resizing looks to be all single pixel based in the Tk backend as opposed to lengths. You can't, e.g., take the 4.5th pixel or make something 80.493 pixels long. I don't see any non-integer manipulation functions in tkImgPhoto.h

      Your answer sounded so logical, I immediately tried it out. But it turns out that GD returns its data as real raw data, like it should be stored in a file, and that Tk::Photo takes data the way it produces it with the data() method, that is an ASCII string. Very strange, and I have no clue why anyone would want such a string...

      So if anyone knows how to convert between these different formats, please let me know.

      Jouke Visser, Perl 'Adept'
Re: Resizing images && Tk
by Jouke (Curate) on Mar 14, 2001 at 17:32 UTC
    The solution to this question can be found in this node

    Jouke Visser, Perl 'Adept'