How To Upload and Resize an Image with PHP

Posted on: August 12th, 2015 by BuildMyWeb No Comments

Upload an Image to Your Server with PHP

You can relatively easily upload images to your web host using an HTML form and a PHP script handler. The key ingredient is to include the following within your form element: enctype="multipart/form-data". And, of course, you will need the proper input that allows users to select and upload the file: <input type="file" name="file_upload"> .


    <form id="Upload" action="scripts/handler_upload.php" enctype="multipart/form-data" method="post">      
        <input type="hidden" name="max_file_size" value="<?php echo $max_file_size; ?>"> 
         
        <label for="file">File to upload:</label> 
        <input type="file" name="file_upload"> 
                 
        <input id="submit" type="submit" name="submit" value="Upload me!">      
    </form> 

When allowing users to upload any file to your server in this way, you are opening your server up to added security vulnerabilities. There are things you can do to mitigate a large number of these vulnerabilities and I would not allow users to upload files without researching this subject yourself as it is not covered under the scope of this article. You can limit the size and types of files that can be uploaded, for instance. If the purpose of this project is to allow users to upload profile pictures, why not limit the upload possibilities to an array of image formats: $permitted_extensions = array('jpg', 'jpeg', 'gif', ...); This article is not so much about uploading an image with PHP. That is covered extensively throughout the internet. This article is more concerned with resizing and cropping them. Something I had a much more difficult time finding good information on.

Resize and Crop Your Image

This single PHP Class allows one to resize and crop images dynamically and without distortion. Or with it if you prefer. There are options that will allow you to keep the aspect ratio intact or to force specific height and width dimensions. With the functions already built into this class, you can also save images to several different types of your choosing with adjustable quality. Best of all, it is basically plug-n-play.

The one major caveat is that it requires the PHP GD Library be installed on your server. If you’re unsure if your hosting provider has this installed, follow these instructions on phpinfo() to find out for sure.

Simply place the class into a file on your server. In this case, the call will be looking for resize-class.php. Use the Class Call to instantiate the class object. Be sure to edit path values to find your file(s) and save to the desired locations.

The Class Call

// *** Include the class if you don't have an autoloader
include("resize-class.php");
 
// *** 1) Initialize / load image you want to work on
$resizeObj = new resize('sample.jpg');
 
// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
$resizeObj -> resizeImage(150, 100, 'crop');
 
// *** 3) Save image
$resizeObj -> saveImage('sample-resized.gif', 100);

The Class


class resize
{
    private $image;
    private $width;
    private $height;
    private $imageResized;
 
    function __construct($fileName)
    {
        // *** Open up the file
        $this->image = $this->openImage($fileName);
 
        // *** Get width and height
        $this->width  = imagesx($this->image);
        $this->height = imagesy($this->image);
    }
    
    private function openImage($file)
    {
        // *** Get extension
        $extension = strtolower(strrchr($file, '.'));
     
        switch($extension)
        {
            case '.jpg':
            case '.jpeg':
                $img = @imagecreatefromjpeg($file);
                break;
            case '.gif':
                $img = @imagecreatefromgif($file);
                break;
            case '.png':
                $img = @imagecreatefrompng($file);
                break;
            default:
                $img = false;
                break;
        }
        return $img;
    }
    
    public function resizeImage($newWidth, $newHeight, $option="auto")
    {    
        // *** Get optimal width and height - based on $option
        $optionArray = $this->getDimensions($newWidth, $newHeight, strtolower($option));
     
        $optimalWidth  = $optionArray['optimalWidth'];
        $optimalHeight = $optionArray['optimalHeight'];
     
        // *** Resample - create image canvas of x, y size
        $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
        imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight,
        $this->width, $this->height);
     
        // *** if option is 'crop', then crop too
        if ($option == 'crop') {
            $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
        }
    }
    
    private function getDimensions($newWidth, $newHeight, $option)
    {
     
       switch ($option)
        {
            case 'exact':
                $optimalWidth = $newWidth;
                $optimalHeight= $newHeight;
                break;
            case 'portrait':
                $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                $optimalHeight= $newHeight;
                break;
            case 'landscape':
                $optimalWidth = $newWidth;
                $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                break;
            case 'auto':
                $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
                $optimalWidth = $optionArray['optimalWidth'];
                $optimalHeight = $optionArray['optimalHeight'];
                break;
            case 'crop':
                $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
                $optimalWidth = $optionArray['optimalWidth'];
                $optimalHeight = $optionArray['optimalHeight'];
                break;
        }
        return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    }
    
    private function getSizeByFixedHeight($newHeight)
    {
        $ratio = $this->width / $this->height;
        $newWidth = $newHeight * $ratio;
        return $newWidth;
    }
     
    private function getSizeByFixedWidth($newWidth)
    {
        $ratio = $this->height / $this->width;
        $newHeight = $newWidth * $ratio;
        return $newHeight;
    }
     
    private function getSizeByAuto($newWidth, $newHeight)
    {
        if ($this->height < $this->width)
        // *** Image to be resized is wider (landscape)
        {
            $optimalWidth = $newWidth;
            $optimalHeight= $this->getSizeByFixedWidth($newWidth);
        }
        elseif ($this->height > $this->width)
        // *** Image to be resized is taller (portrait)
        {
            $optimalWidth = $this->getSizeByFixedHeight($newHeight);
            $optimalHeight= $newHeight;
        }
        else
        // *** Image to be resizerd is a square
        {
            if ($newHeight < $newWidth) {
                $optimalWidth = $newWidth;
                $optimalHeight= $this->getSizeByFixedWidth($newWidth);
            } else if ($newHeight > $newWidth) {
                $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                $optimalHeight= $newHeight;
            } else {
                // *** Sqaure being resized to a square
                $optimalWidth = $newWidth;
                $optimalHeight= $newHeight;
            }
        }
     
        return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    }
     
    private function getOptimalCrop($newWidth, $newHeight)
    {
     
        $heightRatio = $this->height / $newHeight;
        $widthRatio  = $this->width /  $newWidth;
     
        if ($heightRatio < $widthRatio) {
            $optimalRatio = $heightRatio;
        } else {
            $optimalRatio = $widthRatio;
        }
     
        $optimalHeight = $this->height / $optimalRatio;
        $optimalWidth  = $this->width  / $optimalRatio;
     
        return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    }
    
    private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
    {
        // *** Find center - this will be used for the crop
        $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
        $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
     
        $crop = $this->imageResized;
        //imagedestroy($this->imageResized);
     
        // *** Now crop from center to exact requested size
        $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
        imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth,
        $newHeight, $newWidth, $newHeight);
    }
    
    public function saveImage($savePath, $imageQuality="80")
    {
        // *** Get extension
        $extension = strrchr($savePath, '.');
        $extension = strtolower($extension);
     
        switch($extension)
        {
            case '.jpg':
            case '.jpeg':
                if (imagetypes() & IMG_JPG) {
                    imagejpeg($this->imageResized, $savePath, $imageQuality);
                }
                break;
     
            case '.gif':
                if (imagetypes() & IMG_GIF) {
                    imagegif($this->imageResized, $savePath);
                }
                break;
     
            case '.png':
                // *** Scale quality from 0-100 to 0-9
                $scaleQuality = round(($imageQuality/100) * 9);
     
                // *** Invert quality setting as 0 is best, not 9
                $invertScaleQuality = 9 - $scaleQuality;
     
                if (imagetypes() & IMG_PNG) {
                    imagepng($this->imageResized, $savePath, $invertScaleQuality);
                }
                break;
     
            // ... etc
     
            default:
                // *** No extension - No save.
                break;
        }
     
        imagedestroy($this->imageResized);
    }
}

Source

http://code.tutsplus.com/tutorials/image-resizing-made-easy-with-php–net-10362

Tags:

Leave a Reply