image resize - doesn't work as wanted.

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
JKM
Forum Contributor
Posts: 221
Joined: Tue Jun 17, 2008 8:12 pm

image resize - doesn't work as wanted.

Post by JKM »

I've got this image upload script that should resize images that's larger than 204px*250px. When I uploaded a image 400px*575px, it resized the image to 204px*293px.

Code: Select all

<?php
$origimg = $_FILES['pix']['tmp_name'];
$imagedata = getimagesize($origimg);
$maxw = 204;
$maxh = 250;
$rand = rand(1,100);
$pixname = 'pix/'.$_GET['id'].'_'.$rand.'.jpg';
if(($maxw != $imagedata[0]) && ($maxh != $imagedata[1])) {
    if(($maxw < $imagedata[0]) || ($maxh < $imagedata[1])) {
        if($imagedata[0] > $imagedata[1]) {
            $newpercent = $imagedata[0]/$maxh;
            $newimgw = $imagedata[0]/$newpercent;
            $newimgh = $imagedata[1]/$newpercent;
            $newimg = imagecreatetruecolor($newimgw, $newimgh);
            $oldimg = imagecreatefromjpeg($origimg);
            imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $newimgw, $newimgh, $imagedata[0], $imagedata[1]);
            imagejpeg($newimg, $pixname, 100);
            $marginw = ($newimgw-$maxw)/2;
            $marginh = 0;
        } else {
            $newpercent = $imagedata[0]/$maxw;
            $newimgw = $imagedata[0]/$newpercent;
            $newimgh = $imagedata[1]/$newpercent;
            $newimg = imagecreatetruecolor($newimgw, $newimgh);
            $oldimg = imagecreatefromjpeg($origimg);
            imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $newimgw, $newimgh, $imagedata[0], $imagedata[1]);
            imagejpeg($newimg, $pixname, 100);
            $marginw = 0;
            $marginh = 0;
        }
    } else {
        $newimg = imagecreatetruecolor($imagedata[0], $imagedata[1]);
        $oldimg = imagecreatefromjpeg($origimg);
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $imagedata[0], $imagedata[1], $imagedata[0], $imagedata[1]);
        imagejpeg($newimg, $pixname, 100);
        $marginw = ($maxw-$imagedata[0])/2;
        $marginh = 0;
    }
} else {
        $newimg = imagecreatetruecolor($maxw, $maxh);
        $oldimg = imagecreatefromjpeg($origimg);
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $maxw, $maxh, $maxw, $maxh);
        imagejpeg($newimg, $pixname, 100);
        $marginw = 0;
        $marginh = 0;
}
if($marginw != 0) {
    $marginw1 = round($marginw).'px';
} elseif($marginh != 0) {
    $marginh1 = round($marginh).'px';
} else {
    $marginw1 = round($marginw);
    $marginh1 = round($marginh);
}
$margin = $marginh1.','.$marginw1;
?>
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: image resize - doesn't work as wanted.

Post by requinix »

There's actually three bugs in there.

With comments:

Code: Select all

if($imagedata[0] > $imagedata[1]) { // if the image is wider than tall
    $newpercent = $imagedata[0]/$maxh; // ratio is the current width to maximum height
 
} else { // if the image is not wider than tall
    $newpercent = $imagedata[0]/$maxw; // ratio is the current width to maximum width
 
When thumbnailing this way, you need to find the ratio that means the largest decrease in size. The two possible are old-width:new-width and old-height:new-height. Use the one that's greater for the greatest reduction in size; if you use the smaller one than you'll resize by the smallest amount.

Code: Select all

400x575 -> 204x250
 
width ratio:  400/204 = 1.96
    400/1.96 = 204
    575/1.96 = 293  -> 204x293 thumbnail
height ratio: 575/250 = 2.3
    400/2.3  = 173
    575/2.3  = 250  -> 173x250 thumbnail
(So: the first bug was the ratio using width-A-to-height-B, the second was the way you computed which ratio to use, the third was having the ratios swapped (but that one doesn't matter))
JKM
Forum Contributor
Posts: 221
Joined: Tue Jun 17, 2008 8:12 pm

Re: image resize - doesn't work as wanted.

Post by JKM »

tasairis wrote:(So: the first bug was the ratio using width-A-to-height-B, the second was the way you computed which ratio to use, the third was having the ratios swapped (but that one doesn't matter))
I've tried some different codes now, and I'm pretty stuck. Could you please help me out? :)
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: image resize - doesn't work as wanted.

Post by requinix »

You'll have to change your code, you can't just fix the bugs. That is, fixing the bugs means writing some of your PHP.

Instead of comparing widths and heights you need to compare ratios. Figure out the old-width/new-width ratio, the old-height/new-height ratio, and use the larger of the two to compute the thumbnail's dimensions.
Then

Code: Select all

new-width  = old-width  / ratio
new-height = old-height / ratio
JKM
Forum Contributor
Posts: 221
Joined: Tue Jun 17, 2008 8:12 pm

Re: image resize - doesn't work as wanted.

Post by JKM »

I'm a bit stuck here - sorry If I'm slow minded :p

I made a new code, and it's working better (in a way)..

Code: Select all

if($_POST['newpix'])
{
    $origimg = $_FILES['pix']['tmp_name'];
    $imagedata = getimagesize($origimg);
    $maxw = 204;
    $maxh = 250;
    $rand = date('U');
    $pixname = 'pix/intro/'.$_GET['id'].'_'.$rand.'.jpg';
    $pname = $_GET['aID'].'_'.$rand.'.jpg';
    $imagewidth = $imagedata[0];
    $imageheight = $imagedata[1];
    if(($imagewidth > $maxw) || ($imageheight > $maxh))
    {
        if($imagewidth > $imageheight)
        {
            $lol = '1';
            $newimgw = $maxw;
            $ratio = $maxh/$imageheight;
            $newimgh = $imageheight*$ratio;
        } elseif($imageheight > $imagewidth)
        {
            $lol = '2';
            $newimgh = $maxh;
            $ratio = $maxw/$imageheight;
            $newimgw = $imagewidth*$ratio;          
        } else
        {
            $lol = '3';
            $newimgh = $maxh;
            $newimgw = $maxw;
        }
        $marg = ($newimgw-$maxw)/2;
        $newimg = imagecreatetruecolor($newimgw, $newimgh);
        $oldimg = imagecreatefromjpeg($origimg);
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $newimgw, $newimgh, $imagewidth, $imageheight);
        imagejpeg($newimg, $pixname, 100);
    } else
    {
        $newimg = imagecreatetruecolor($imagewidth, $imageheight);
        $oldimg = imagecreatefromjpeg($origimg);
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $imagewidth, $imageheight, $imagewidth, $imageheight);
        imagejpeg($newimg, $pixname, 100);
        $marg = ($maxw-$imagewidth)/2;
    }
    $margin = round($marg);
} else
    {
    $pname = $fetch['pix'];
    $margin = $fetch['pixM'];
}
echo '$lol='.$lol;
echo '<br />';
echo '$newimgw='.$newimgw;
echo '<br />';
echo '$ratio='. $ratio;
echo '<br />';
echo '$newimgh='.$newimgh;
echo '<br />';
echo '$imageheight='.$imageheight;
echo '<br />';
echo '$imagewidth='.$imagewidth;
Result:
$lol=2
$newimgw=139.975384615
$ratio=0.313846153846
$newimgw=250
$imageheight=650
$imagewidth=446
I tried to resize the same image in Photoshop. With 250px as height, width returned 172px.
- The height ratio should be 0,313846153846.
- The width ratio should be 0,392376 (172/446 - 172 photoshop | 446 original width)
- 0,392376*650=255 (so the width ratio wouldn't work out for the height resize).
This means that I must have two different ratios, and the problem is how to find the width ratio (and the height ratio when the width > height).

Thanks for the help.
JKM
Forum Contributor
Posts: 221
Joined: Tue Jun 17, 2008 8:12 pm

Re: image resize - doesn't work as wanted.

Post by JKM »

Okay, I've got it figured with the resize etc. But there is a problem when uploading png/gif files.

When uploading a png file with the following dimensions: 298px × 332px, the script returned:

Code: Select all

Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in settings.php on line 156
 
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: '/tmp/php0FPWCd' is not a valid JPEG file in settings.php on line 157
 
Warning: imagecopyresampled(): supplied argument is not a valid Image resource in /settings.php on line 158
 
Warning: imagejpeg(): supplied argument is not a valid Image resource in settings.php on line 159
The code:

Code: Select all

if($_POST['newimg']) {
    $origimg = $_FILES['img']['tmp_name'];
    $imagedata = getimagesize($origimg);
    $maxw = 204;
    $maxh = 250;
    $rand = date('U');
    $pixname = 'pix/'.'_'.$rand.'.jpg';
    $pname = '_'.$rand.'.jpg';
    $imagewidth = $imagedata[0];
    $imageheight = $imagedata[1];
    $maxratio = $maxh/$maxw;
    $imageratio = $imageheight/$imagewidth;
    if(($imagewidth > $maxw) || ($imageheight > $maxh)) {
        if($maxratio > $imageratio) {
            $newimgw = $maxw;
            $newimgh = ($maxw/$imagewidth)*$imageheigth;
        }
        else {
            $newimgh = $maxh;
            $newimgw = ($maxh/$imageheight)*$imagewidth;
        }
        $marg = ($maxw-$newimgw)/2;
        $newimg = imagecreatetruecolor($newimgw, $newimgh); // line 156
        $oldimg = imagecreatefromjpeg($origimg); // line 157
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $newimgw, $newimgh, $imagewidth, $imageheight); // line 158
        imagejpeg($newimg, $pixname, 100); // line 159
    } else {
        $newimg = imagecreatetruecolor($imagewidth, $imageheight);
        $oldimg = imagecreatefromjpeg($origimg);
        imagecopyresampled($newimg, $oldimg, 0, 0, 0, 0, $imagewidth, $imageheight, $imagewidth, $imageheight);
        imagejpeg($newimg, $pixname, 100);
        $marg = ($imagewidth-$maxw)/2;
    }
    $margin = round($marg);
} else {
    $pname = $fetch['img'];
    $margin = $fetch['imgm'];
}
Post Reply