ZizzyDizzyMC
ZizzyDizzyMC

Reputation: 73

Resize an image in php with max height and width

Ok so I'm trying to resize an image using php. I do not have access to install plugins on the server I use at this time.

$originalimage is the actual original image that I'm going to resize. $width is another parameter to define $original_width. The same can be said for $height and $original_height.

$original_width = imagesx($originalimage);
$original_height = imagesy($originalimage);

$max_width = $thumbwidth;
$max_height = $thumbheight;

$width = $original_width;
$height = $original_height;

Using the pre-setup above I start to work on this one here. This works but no way to set a max height. For example I pass a max width as $thumbwidth and max height as $thumbheight and this will work as desired till I then try to go ahead and use an image that's higher than it is wide. (Portrait image.) It does not completely fail however it does fail to enforce a max height, rendering an image that can potentially be very high.

if ($width > $height) {
$newwidth = $thumbwidth;
$divisor = $width / $thumbwidth;
$newheight = floor( $height / $divisor);
} else {
$newheight = $thumbheight;
$divisor = $height / $thumbheight;
$newwidth = floor( $width / $divisor );
}
$image = imagecreatetruecolor( $newwidth, $newheight );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $newwidth, $newheight, $original_width, $original_height );

After trying to understand this and failing after a few hours I came up with the code below which I had gotten from php.net. As you can see there was a reason I set two sets of variables equal to each other in the pre-setup part of the code. Mostly because I can not comprehend calling $max_width as $thumbwidth in the second code segment. This below works as well until you pass in a parameter though that is larger than the width or height of $originalimage.

# taller
if ($height > $max_height) {
    $width = ($max_height / $height) * $width;
    $height = $max_height;
}

# wider
if ($width > $max_width) {
    $height = ($max_width / $width) * $height;
    $width = $max_width;
}


$image = imagecreatetruecolor( $width, $height );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $width, $height, $original_width, $original_height );

I'm sorry I can't find a way to do this on my own. As for this being a duplicate question, Most similar questions end up with "[Insert plugin name here] is better use that instead." I am asking specifically for an answer that does not use other plugins or javascript. (Besides GD which is pre-installed on my server.) Before I end this question I will say that I am using imagejpeg($image); so the use of HTML or CSS is completely forbidden.

Upvotes: 1

Views: 3110

Answers (2)

M61Vulcan
M61Vulcan

Reputation: 337

I've had a very similar problem building the thumbs for a gallery page. I tried Daniel Nyamasyo solution above but just could not get past the "$img = imagecreatefromjpeg($sourcefile);" line without getting "Warning: imagecreatefromjpeg failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request" no matter what $sourcefile I fed it. I came up with this dirty method.

    <?php
    // Some variables
    $thumb_width = 162; // The maximum values you want
    $thumb_height = 122;
    $thumb_pointer = 'thumbs';  // Put your output folder here which must exist

    $img = imagecreatefromjpeg( $image_name);
    $width = imagesx( $img );
    $height = imagesy( $img );
    if ($width>=$height)
    {
        // Now calculate thumbnail size
        $new_width = $thumb_width;
        $new_height = floor( $height * ($thumb_width / $width));
        // The 'dirty' bit I found was needed for square or near square images      
        while ($new_height > $thumb_height)
        {
            $new_width = floor($new_width * 0.99);
            $new_height = floor($new_height * 0.99);
        }
    }
    else
    {
        $new_height = $thumb_height;
        $new_width =  floor($width * ($thumb_height / $height));
    }
    // Create a new temporary image 
    $tmp_img = imagecreatetruecolor( $new_width, $new_height );
    // Copy and resize old image into new image 
    imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
    // Save the thumbnail into a file   
    imagejpeg( $tmp_img, $thumb_pointer.'/'.$image_name);
?>

Upvotes: 0

Joe Meyer
Joe Meyer

Reputation: 4405

Here's a class I whipped up for a program I worked on. maybe it will help you?

<?php
class ImageHelper
{
    /**
     * @static
     * @param $source string Path for source image
     * @param $destination string Path for destination image to be placed
     * @param $targetWidth int Width of the new image (in pixels)
     * @param $targetHeight int Height of the new image (in pixels)
     * @param $strict bool
     */
    public static function createImage($source, $destination, $targetWidth, $targetHeight, $strict = false){
        $dir = dirname($destination);
        if(!is_dir($dir)){
            mkdir($dir, 0770, true);
        }
        $fileContents = file_get_contents($source);
        $image = imagecreatefromstring($fileContents);

        $thumbnail = ImageHelper::resizeImage($image, $targetWidth, $targetHeight, $strict);
        imagejpeg($thumbnail, $destination, 100);
        imagedestroy($thumbnail);
        imagedestroy($image);
    }

    /**
     * Resize an image to the specified dimensions
     * @param string $original Path to the original image
     * @param int $targetWidth Width of the new image (in pixels)
     * @param int $targetHeight Height of the new image (in pixels)
     * @param bool $strict True to crop the picture to the specified dimensions, false for best fit
     * @return bool|resource Returns the new image resource or false if the image was not resized.
     */
    public static function resizeImage($original, $targetWidth, $targetHeight, $strict = false)
    {
        $originalWidth = imagesx($original);
        $originalHeight = imagesy($original);

        $widthRatio = $targetWidth / $originalWidth;
        $heightRatio = $targetHeight / $originalHeight;

        if(($widthRatio > 1 || $heightRatio > 1) && !$strict){
            // don't scale up an image if either targets are greater than the original sizes and we aren't using a strict parameter
            $dstHeight = $originalHeight;
            $dstWidth = $originalWidth;
            $srcHeight = $originalHeight;
            $srcWidth = $originalWidth;
            $srcX = 0;
            $srcY = 0;
        }elseif ($widthRatio > $heightRatio) {
            // width is the constraining factor
            if ($strict) {
                $dstHeight = $targetHeight;
                $dstWidth = $targetWidth;
                $srcHeight = $originalHeight;
                $srcWidth = $heightRatio * $targetWidth;
                $srcX = floor(($originalWidth - $srcWidth) / 2);
                $srcY = 0;
            } else {
                $dstHeight = ($originalHeight * $targetWidth) / $originalWidth;
                $dstWidth = $targetWidth;
                $srcHeight = $originalHeight;
                $srcWidth = $originalWidth;
                $srcX = 0;
                $srcY = 0;
            }
        } else {
            // height is the constraining factor
            if ($strict) {
                $dstHeight = $targetHeight;
                $dstWidth = $targetWidth;
                $srcHeight = $widthRatio * $targetHeight;
                $srcWidth = $originalWidth;
                $srcY = floor(($originalHeight - $srcHeight) / 2);
                $srcX = 0;
            } else {
                $dstHeight = $targetHeight;
                $dstWidth = ($originalWidth * $targetHeight) / $originalHeight;
                $srcHeight = $originalHeight;
                $srcWidth = $originalWidth;
                $srcX = 0;
                $srcY = 0;
            }
        }

        $new = imagecreatetruecolor($dstWidth, $dstHeight);
        if ($new === false) {
            return false;
        }

        imagecopyresampled($new, $original, 0, 0, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight);

        return $new;
    }

}

Upvotes: 1

Related Questions