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

Greetings and salutions;

I am using a subroutine I found to obtain the dimansions of a gif image. The sub returns a reference to the data but when I attempt to dereference it ie. $$height or $$width I get SCALAR(0xed880) SCALAR(0xed898) instead of the values I'm looking for. I have tried returning the vars $height and $width directly but the data they contain is innacurate when compared to the original image.

Does the expression: return \($width, $height);
require some other syntax to dereference properly?

Should the syntax be: return (\$width, \$height);
to dereference properly?

This is how I am attempting to use the subroutine:

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Display the uploaded file. # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # $MyFileName = "$ClassPath/classimg/$UpLoadedImg"; if (-e $MyFileName){ ($width, $height) = gifdim($MyFileName); if ($$height > 150){ # If the image is too tall for the display area # reduce the height to fit and recalculate the width $NewHeight = 150; $NewWidth = $$width - ($$height - 150); } elsif ($width > 150){ # If the image is too wide for the display area # reduce the width to fit and recalcualte the height $NewWidth = 150; $NewHeight = $$height - ($$width - 150); } # The image will fit in the display area so leave it alone else { $NewHeight = $$height; $NewWidth = $$width; } } # more code ... sub gifdim ($) { # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Get the dimensions of a gif # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # my $filename = $_[0]; open(GIF, $filename) || return (undef, undef); my $buf = ''; my $n = read GIF, $buf, 10; close GIF; return (undef, undef) if $n < 10; my ($head, $width, $height) = unpack("A6vv", $buf); ($head, $width, $height) = unpack("A6vv", $buf); return (undef, undef) unless $head =~ /^GIF8[79]a/; return \($width, $height); # return ($width, $height); }
I'm sure I'm missing something obvous but I'm stumped

My thanks to The Monastery
NereDoWell

Replies are listed 'Best First'.
Re: dereferencing problem
by Mr. Muskrat (Canon) on Mar 14, 2003 at 22:14 UTC

    Once suggestion from me... drop that subroutine like a hot potato and use Image::Info for retreiving the image information!

    use Image::Info qw(dim); my $MyFileName = "$ClassPath/classimg/$UpLoadedImg"; my ($width, $height); if (-e $MyFileName){ my $info = image_info($MyFileName); ($width, $height) = dim($info); ...

Re: dereferencing problem
by dga (Hermit) on Mar 14, 2003 at 22:11 UTC

    Briefly looking at your code, I would try removing all the \$ and $$ stuff and I think it will be a good start.

    Use the return( $width, $height ); and get rid of the other one. Then in the main script you test like so.

    if($height > 150 ) { # ... } elsif($width > 150) { # ... stuff here } # ... more stuff here

    In this program you dont need any references just the regular values $var etc.

    Update: You might also try scaling the images by the same percent instead of by the same numeric amount. Say its 200x100 then 150/200 is .75 so make the 100 dimension 75 (100*.75) instead of 50 (100-(200-150)) like the current code would.

      dga
      Many thanks;

      I got sidetracked to the dereferencing when I got the wrong values for height and width from the subroutine. After scrapping that and going back to using the vars directly I noticed that I was still sending the default image to the sub. There was no way the sub could return the values I was looking for. All is now well. I also took your advice and altered the resizing to a percentage.

      I would also like to say thank you here to bbfu and Mr. Muskrat for their help and advice.

      NereDoWell

Re: dereferencing problem
by bbfu (Curate) on Mar 14, 2003 at 22:12 UTC

    Use the line that's commented (return ($width, $height);) instead of the one w/ the backslash. There's no reason to return references in this case. (Update: Oh yes, and of course remove all the dereferencing.)

    If you get inaccurate results then, then it's a problem with the routine and you should scrap it. Some possible alternates include GD and Image::Magick.

    Update: Oh, and just FYI, the two lines:

    return \($width, $height); # and... return (\$width, \$height);

    do exactly the same thing. In other words, taking a reference to a list (not an array, mind you) returns a list whose elements are all references to the elements in the original list.

    bbfu
    Black flowers blossum
    Fearless on my breath

Re: dereferencing problem
by thpfft (Chaplain) on Mar 15, 2003 at 17:53 UTC
Re: dereferencing problem
by Desdinova (Friar) on Mar 14, 2003 at 22:49 UTC
    First the others are right there is no real reason to complcate this with references a simple copy by value is fine here, and there is no need to redo what has been done...

    Now looking at the question I have to say that I grabbed your code and stripped to the most simple form and tested it. It doesn't have the derefeencing problem you mention
    ($width, $height) = gifdim('test_text'); print "Height = $$height Width = $$width \n"; exit; sub gifdim ($) { my $filename = $_[0]; my $height =200; my $width =300; return \($width, $height); }
    output:Height = 200 Width = 300

    So im not sure what problem you are having.
      Desdinova;

      Thanks for looking. I have stopped using the reference and I am now returning the vars by value. My true error was in failing to send the proper image to the subroutine. This obvously returned values that did not match the image I was maniplating. Since the original subroutine returned references I thought I might have introduced an error when I changed it. I tried using the references to check this and got sidetracked.

      Just why $$var gave me SCALAR(0xed880) instead of the value located at \$var I don't know but since the new structure works I'll come back to that issue later.

      Thanks and Thanks again to all
      NereDoWell