Image upload function performs the task of image uploading, cropping, setting image size according to aspect ratio etc. This PHP code provides the fully functional image upload utility.

Here is the code –

    array('http://localhost','https://dunebook.com'),
                                'destination'   =>   {where to save image?},
                                'allowed-ext'   =>   array('jpg','jpeg','png','gif'),
                                'allowed-size'  =>   {5MB},
                                'field-name'    =>   {img1},
                                'image-name'    =>   {image_name, auto, preference, custom},
                                'resize'        =>   array(
                                                        'new-width'     =>   {new image width},
                                                        'new-height'    =>   {new image height},
                                                        'resize-type'   =>   {1|2|3},
                                                        'gif-no-resize' =>   {0|1}
                                                    ),
                                'crop'          =>   array(
                                                        'x1'    =>   {top left x-coordinate},
                                                        'y1'    =>   {top left y-coordinate},
                                                        'x2'    =>   {bottom right x-coordinate},
                                                        'y2'    =>   {bottom right y-coordinate},
                                                        'width' =>   {width of image at the time of cropping},
                                                        'height'=>   {height of image at the time of cropping}
                                                    )
                        );

    Output:

            array('status'=>1,'image'=>{name of image});
            array('status'=>0,'error'=>{1|2|3|4|5|6|7|8|9|10|11|12});

                            error   ->   1 - Error occurred in form submission.
                                        2 - 'field-name' is not set.
                                        3 - image uploaded from domain not in origin array.
                                        4 - uploaded image doesn't have valid name.
                                        5 - Image extension is invalid.
                                        6 - Provided image size is invalid. It should be in this format 123MB or 123KB
                                        7 - uploaded image size is greater than approved size.
                                        8 - 'destination' for image upload is not set.
                                        9 - 'image-name' is invalid. It can only be auto, preference, image-name or any valid custom name.
                                        10 - Some error occurred. Either destination directory is not writable or there is no directory at provided destination. If relative path is not working, then try to provide complete path from root to destination folder.
                                        11 - Error in 'new-width' and/or 'new-height' field of 'resize'.
                                        12 - Error in 'x1', 'y1', 'x2', 'y2' value of 'crop'. Remember, x1 should be less than x2 and y1 should be less than y2. All values should be numeric.

*/
function image_upload_function($image_array)
{
    global $_FILES;

    if(!isset($image_array['field-name']) || empty($image_array['field-name']))
        return array('status'=>0,'error'=>2);

    if(!isset($image_array['destination']) || empty($image_array['destination']))
        return array('status'=>0,'error'=>8);

    $destination = $image_array['destination'];

    $temp = $_FILES[$image_array['field-name']];

    if (is_uploaded_file($temp['tmp_name'])){
        if(isset($image_array['origin']) && is_array($image_array['origin']) && !empty($image_array['origin']))
        {
            if (isset($_SERVER['HTTP_ORIGIN'])) {
                if (!in_array($_SERVER['HTTP_ORIGIN'], $image_array['origin'])) {
                    return array('status'=>0,'error'=>3);
                }
            }   
        }
        if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
            return array('status'=>0,'error'=>4);
        }

        $allowed = array("gif", "jpg", "jpeg", "png");

        if(isset($image_array['allowed-ext']) && is_array($image_array['allowed-ext']) && !empty($image_array['allowed-ext']))
            $allowed = $image_array['allowed-ext'];

        $ext = strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION));

        if (!in_array($ext, $allowed)) {
            return array('status'=>0,'error'=>5);
        }

        $size = 1024*1024*5;

        if(isset($image_array['allowed-size']) && !empty($image_array['allowed-size']))
        {
            $size = strtolower($image_array['allowed-size']);
            $size_ext = trim(substr($size, -2));
            $size = intval(trim(substr($size,0,-2)))*1024;
            if($size_ext == 'kb');
            else if($size_ext == 'mb')
                $size = $size*1024;
            else if($size_ext == 'gb')
                $size = $size*1024*1024;
            else
                return array('status'=>0,'error'=>6);
        }

        if($size 0,'error'=>7);

        $image_name = 'auto';   

        if(isset($image_array['image-name']) && !empty($image_array['image-name']))
        {
            $image_name = $image_array['image-name'];
        }   

        if(preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $image_name))
            return array('status'=>0,'error'=>9);

        if($image_name == 'preference')
        {
            $lol = glob($destination.$temp['name']);
            if(is_array($lol) && empty($lol))
                $image_name = $temp['name'];
            else
                $image_name = 'auto';
        }

        if($image_name == 'auto')
            $image_name = time().mt_rand().$temp['name'];
        else if($image_name == 'image_name')
            $image_name = $temp['name'];
        else
            $image_name = $image_name.'.'.$ext;

        $actual_image = $destination.$image_name;   

        if(isset($image_array['resize']) && is_array($image_array['resize']) && !empty($image_array['resize']))
        {
            if((isset($image_array['resize']['new-width']) && is_numeric($image_array['resize']['new-width'])) || (isset($image_array['resize']['new-height']) && is_numeric($image_array['resize']['new-height']))){

                $gif_no_resize = 1;

                if(isset($image_array['resize']['gif-no-resize']) && $image_array['resize']['gif-no-resize'] === 0)
                    $gif_no_resize = 0;

                if(isset($image_array['resize']['new-width']) && isset($image_array['resize']['new-height']))
                {
                    $resize_type = 3;
                    if(isset($image_array['resize']['resize-type']) && is_numeric($image_array['resize']['resize-type']) && $image_array['resize']['resize-type']>=1 && $image_array['resize']['resize-type']1,'image'=>$image_name, 'original-image-size'=>array('width'=>$act[0],'height'=>$act[1]), 'new-image-size'=>array('width'=>$act1[0],'height'=>$act1[1]));
            }
            else{
                return array('status'=>0,'error'=>11);
            }
        }
        else if(isset($image_array['crop']) && is_array($image_array['crop']) && !empty($image_array['crop']))
        {
            if((isset($image_array['crop']['x1']) && is_numeric($image_array['crop']['x1'])) && (isset($image_array['crop']['y1']) && is_numeric($image_array['crop']['y1'])) && (isset($image_array['crop']['x2']) && is_numeric($image_array['crop']['x2'])) && (isset($image_array['crop']['y2']) && is_numeric($image_array['crop']['y2'])) && ($image_array['crop']['x1'] < $image_array['crop']['x2']) && ($image_array['crop']['y1'] 1,'image'=>$image_name, 'original-image-size'=>array('width'=>$act[0],'height'=>$act[1]), 'new-image-size'=>array('width'=>$act1[0],'height'=>$act1[1]));
            }
            else
                return array('status'=>0,'error'=>12);
        }
        else
        {
            if(move_uploaded_file($temp['tmp_name'], $actual_image)){
                $act = getimagesize($temp['tmp_name']);
                $act1 = getimagesize($actual_image);
                return array('status'=>1,'image'=>$image_name, 'original-image-size'=>array('width'=>$act[0],'height'=>$act[1]), 'new-image-size'=>array('width'=>$act1[0],'height'=>$act1[1]));
            }
            else
                return array('status'=>0,'error'=>10);
        }

    }
    else
        return array('status'=>0,'error'=>1);
}
function propimage($max_width, $max_height, $from_path, $to_path, $ext, $t, $k=0)
{
    $def_asp = $max_width/$max_height;
    $img_size_actual = getimagesize($from_path);
    $img_asp_actual = $img_size_actual[0]/$img_size_actual[1];

    if($t==1 || $t==2)
    {
        if(($t==1 && ($def_asp = $img_asp_actual)))
        {
            if($max_width < $img_size_actual[0])
            {
                $new_width = $max_width;
                $new_height = ($new_width * $img_size_actual[1]) / $img_size_actual[0];
                makeImage($new_width, $new_height, $from_path, $to_path, $img_size_actual[0], $img_size_actual[1], $ext,$k);
            }
            else
            {
                copy($from_path, $to_path);
            }
        }
        else
        {
            if($max_height  255, 'green' => 255, 'blue' => 255);

    if ($transparencyIndex >= 0 && $transparencyIndex < $pallsize) {
        $transparencyColor    = imagecolorsforindex($image_source, $transparencyIndex);   
    }

    $transparencyIndex    = imagecolorallocate($new_image, $transparencyColor['red'], $transparencyColor['green'], $transparencyColor['blue']);
    imagefill($new_image, 0, 0, $transparencyIndex);
    imagecolortransparent($new_image, $transparencyIndex);

} 

How to use Image Upload Function?

We need to pass the $image_array in the image_upload_function. This array contains all the generally required parameters with which we need to upload and edit our image. This function can resize the image while preserving the aspect ratio as well as without it too. The image types supported by it are jpg, jpeg, png, gif only. Although I tried my best to make it a workable general purpose image upload function, it has limitations with gif images. Gif images can be resized, but then they will loose their animation.

If you want to resize gif images while preserving the animation too then please go through this article – How to resize gif images without losing animation?

To use this function – image_upload_function( $image_array );

Format of Input image Array, $image_array

$image_array    =    array(
                                'origin'        =>    array( 'http://localhost', 'https://dunebook.com' ),
                                'destination'    =>    {where to save image?},
                                'allowed-ext'    =>    array( 'jpg', 'jpeg', 'png', 'gif' ),
                                'allowed-size'    =>    {5MB},
                                'field-name'    =>    {img1},
                                'image-name'    =>    {'image_name', 'auto', 'preference', custom},
                                'resize'        =>    array(
                                                        'new-width'     =>    {new image width},
                                                        'new-height'    =>    {new image height},
                                                        'resize-type'     =>    {1|2|3},
                                                        'gif-no-resize'   =>    {0|1}
                                                    ),
                                'crop'            =>    array(
                                                        'x1'    =>    {top left x-coordinate},
                                                        'y1'    =>    {top left y-coordinate},
                                                        'x2'    =>    {bottom right x-coordinate},
                                                        'y2'    =>    {bottom right y-coordinate},
                                                        'width'    =>    {width of image at the time of cropping},
                                                        'height'   =>    {height of image at the time of cropping}
                                                    )
                        );

'origin' – (Optional) (array) This field determines the allowed domains from which image could be uploaded. It is for security purpose. By default, no origin is set.
'destination' – (Required) (string) The location of directory where you wish to upload the image. Relative paths are sufficient but if that doesn't work then try to give complete path from root.
'allowed-ext' – (Optional) (array) The image extensions which are allowed in your application. They could only be jpg, jpeg, gif and png. By default all the four extensions are allowed.
'allowed-size' – (Optional) (string) The maximum size of the image allowed to be uploaded. By default it is 5MB. You need to fill this field with the type like KB, MB, GB. Make sure the maximum upload size in your server configuration should be more or equal to the size you are setting here.
'field-name' – (Required) (string) The name of file type input field of the html form. This is show the function from where to get the image.
'image-name' – (Optional) (string) This field determines the naming convention of the uploaded image. On your server upload directory same name images cannot exist, so we need some naming convention to alter image name in order to upload it successfully. There are 4 options regarding this and the default value is 'auto'.
'image_name' – (string) If you set the value to this, then the actual name of the image will be used. Caution! If an image with the same name and extension as the new uploaded one, exists already then that will get deleted automatically.
'auto' – (string) If you set this, then the program will append a random string to the image name so that it will always be different from the existing images. This is the safe option.
'preference' – (string) If this is set, then the program will first check whether an image with the same name and extension exists or not. If no image with the similar name exists, then the image will be uploaded with its actual name otherwise 'auto' mode will be on. This is the best option to choose.
custom – (string) This is not a value actually. It is used to indicate that you can also provide a custom image name to this field. You can use any valid name here like 'my_image', 'this_is_landscape', 'flowers_of_white_tower', 'gandalf_the_grey' etc. Caution! Existing same name and extension image will be deleted.
'resize' – (Optional) (array) As the field name suggests, this is used when you wish to resize the uploaded image.
'new-width'– (Optional) (integer) The new width you want for your image. If you left this field and set the height, the width will be calculated with height by preserving the actual aspect ratio.
'new-height'– (Optional) (integer) The new height you want for your image. If you won't set this field but set the width, then the height will be calculated with width by preserving the actual aspect ratio.
'resize-type' – (Optional) (integer) This value decides your preferences towards resizing. It works only when you provide both the 'new-width' and 'new-height'. This is important because most of the times we don't want to spoil the actual aspect ratio of the image. Our provided new width and height will not always satisfy the aspect ratio of the input image. So, either width won't be equal to our provided width or height won't be equal to the provided height. This option will decide whether we wish to give preference to height or width or both. By default, the resize value is set to 3.
1 – For wide images, the width will be same as provided width. For long images, the height will be same as provided height.
2 – For wide images, the height will be same as provided height. For long images, the width will be same as provided width.
3 – This option will skew the image. It will generate an image with same width and height, as provided. But the image will be distorted.
'gif-no-resize' – (Optional) (integer) Since our code will destroy the animation if gif would be resized, so there is a solution that we skip resizing the gif images. The default value is 1.
1 – By setting it to 1, we will tell the program that if gif is uploaded, then it should not be resized.
0 – Use this, if you want to resize the gif images too. Animation will be lost.
'crop' – (Optional) (array) Use this field if you are cropping an image. This is essential for profile images where we want a fixed size and undistorted.
'x1' – (Required) (integer) This is the x co-ordinate of top left part of the new desired cropped image.
'y1' – (Required) (integer) This is the y co-ordinate of top left part of the new desired cropped image.
'x2' – (Required) (integer) This is the x co-ordinate of bottom right part of the new desired cropped image.
'y2' – (Required) (integer) This is the y co-ordinate of bottom right part of the new desired cropped image.
'width' – (Optional) (integer) This is required when the image on which cropping is performed, has size different from the original image. For example, if the image size is 300x300px and you are displaying this image in your browser at 150x150px dimensions and cropping occurred according to the co-ordinates of this image at 150x150px, then width needs to be provided as 150.
'height' – (Optional) (integer) Same as the case with width. If nothing is provided then actual image size will be used.

Understanding 'crop'

Understanding the output from image upload function

1.  array(
          'status' => 1,
          'image' => {name of image},
          'original-image-size' => array( 'width'=>{width of image}, 'height'=>{height of image}),
          'new-image-size' => array( 'width'=>{width of image}, 'height'=>{height of image})
);


This shows that the image is successfully uploaded. The name of the uploaded image will be returned along with the size of original as well as the new (resized or crop) image.

  1. array('status'=>0, 'error'=>{1|2|3|4|5|6|7|8|9|10|11|12});

This means something is wrong and the image is failed to upload. Meaning of various error codes are –
1 – Error occurred in form submission.
2 – 'field-name' is not set.
3 – image uploaded from the domain not in origin array.
4 – uploaded image doesn’t have valid name.
5 – Image extension is invalid.
6 – Provided image size is invalid. It should be in this format 123MB or 123KB
7 – uploaded image size is greater than approved size.
8 – ‘destination’ for image upload is not set.
9 – ‘image-name’ is invalid. It can only be auto, preference, image-name or any valid custom name.
10 – Some error occurred. Either destination directory is not writable or there is no directory at provided destination. If relative path is not working, then try to provide complete path from root to destination folder.
11 – Error in ‘new-width’ and/or ‘new-height’ field of ‘resize’.
12 – Error in 'x1', 'y1', 'x2', 'y2' value of ‘crop’. Remember, x1 should be less than x2 and y1 should be less than y2. All values should be numeric.