1

I am having the following block of code in my function:

$target_path = "uploads/";

        $target_path = $target_path . basename( $_FILES['image']['name']);

        if(move_uploaded_file($_FILES['image']['tmp_name'], $target_path))
       {
             echo  "The file ".  basename( $_FILES['image']['name'])." has been uploaded";           
       }      
       else   
       {
            echo "There was an error uploading the file, please try again!";
       }

Now I want to resize the image before uploading. I am using the CodeIgniter framework. I have this code:

$config['upload_path'] = "uploads/";


 $path=$config['upload_path'];

        $config['overwrite'] = FALSE;
        $config['remove_spaces'] = TRUE;
        $config['allowed_types'] = 'gif|jpg|jpeg|png|JPEG|JPG|PNG';
        $config['max_size'] = '1024';
        $config['maintain_ratio'] = TRUE;
        $config['max_width'] = '1000';
        $config['max_height'] = '1000';
        $this->load->library('upload',$config);

But this isn't working properly. I am looking for a good solution where image is uploaded by my specified height and width.

VDP
  • 6,340
  • 4
  • 31
  • 53
Sahil Jariwala
  • 243
  • 2
  • 5
  • 19

2 Answers2

4

This is the function I use to allow our staff to upload product images, it uploads the full size image and two smaller images (I only included the code for one here the tn_ version). It takes the values it does because it's in my controller and can be called from multiple places. $control is the name of the fileUpload control you're using, $path is the save path, $imageName is the from the control and sizes just allows me to specify which versions to make, in my case it receives all, med and tn as options. You could make as many or as few as you need. As VDP mentioned you're limited to under 2mb if you don't change any settings but that's fine for me so I just return an error if it's over that.

I don't use the CI image upload library at all btw. It's just sent to the controller via a normal file upload and ajax. It uses an iframe on the main view to display errors or success.

My Controller upload function:

function doUpload($control, $path, $imageName, $sizes)
{
    if( ! isset($_FILES[$control]) || ! is_uploaded_file($_FILES[$control]['tmp_name']))
    {
        print('No file was chosen');
        return FALSE;
    } 
    if($_FILES[$control]['size']>2048000)
    {
        print('File is too large ('.round(($_FILES[$control]["size"]/1000)).'kb), please choose a file under 2,048kb');
        return FALSE;
    }
    if($_FILES[$control]['error'] !== UPLOAD_ERR_OK)
    {
        print('Upload failed. Error code: '.$_FILES[$control]['error']);
        Return FALSE;
    }
    switch(strtolower($_FILES[$control]['type']))
    {
    case 'image/jpeg':
            $image = imagecreatefromjpeg($_FILES[$control]['tmp_name']);
            move_uploaded_file($_FILES[$control]["tmp_name"],$path.$imageName);
            break;
    case 'image/png':
            $image = imagecreatefrompng($_FILES[$control]['tmp_name']);
            move_uploaded_file($_FILES[$control]["tmp_name"],$path.$imageName);
            break;
    case 'image/gif':
            $image = imagecreatefromgif($_FILES[$control]['tmp_name']);
            move_uploaded_file($_FILES[$control]["tmp_name"],$path.$imageName);
            break;
    default:
           print('This file type is not allowed');
           return false;
    }
    @unlink($_FILES[$control]['tmp_name']);
    $old_width      = imagesx($image);
    $old_height     = imagesy($image);


    //Create tn version
    if($sizes=='tn' || $sizes=='all')
    {
    $max_width = 100;
    $max_height = 100;
    $scale          = min($max_width/$old_width, $max_height/$old_height);
    if ($old_width > 100 || $old_height > 100)
    {
    $new_width      = ceil($scale*$old_width);
    $new_height     = ceil($scale*$old_height);
    } else {
        $new_width = $old_width;
        $new_height = $old_height;
    }
    $new = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new, $image,0, 0, 0, 0,$new_width, $new_height, $old_width, $old_height);
    switch(strtolower($_FILES[$control]['type']))
    {
    case 'image/jpeg':
            imagejpeg($new, $path.'tn_'.$imageName, 90);
            break;
    case 'image/png':
            imagealphablending($new, false);
            imagecopyresampled($new, $image,0, 0, 0, 0,$new_width, $new_height, $old_width, $old_height);
            imagesavealpha($new, true); 
            imagepng($new, $path.'tn_'.$imageName, 0);
            break;
    case 'image/gif':
            imagegif($new, $path.'tn_'.$imageName);
            break;
    default:
    }
    }

    imagedestroy($image);
    imagedestroy($new);
    print '<div style="font-family:arial;"><b>'.$imageName.'</b> Uploaded successfully. Size: '.round($_FILES[$control]['size']/1000).'kb</div>';
}

View HTML:

echo '<input type="file" name="manuLogoUpload" id="manuLogoUpload" onchange="return ajaxFileUpload2(this);"/>';

View ajax call:

        function ajaxFileUpload2(upload_field)
        {
            var re_text = /\.jpg|\.gif|\.jpeg|\.png/i;
            var filename = upload_field.value;
            var imagename = filename.replace("C:\\fakepath\\","");
            if (filename.search(re_text) == -1) 
            {
                alert("File must be an image");
                upload_field.form.reset();
                return false;
            }
            upload_field.form.action = "addManufacturerLogo";
            upload_field.form.target = "upload_iframe";
            upload_field.form.submit();
            upload_field.form.action = "";
            upload_field.form.target = "";
            document.getElementById("logoFileName").value = imagename;
            document.getElementById("logoFileName1").value = imagename;
            document.getElementById("manuLogoText").style.display="block";
            document.getElementById("logoLink").style.display="none";
            $.prettyPhoto.close();
            return true;        
        }

Regular controller function:

function addManufacturerLogo()
{
    $control = 'manuLogoUpload';
    $image = $_FILES[$control]['name'];
    if($imageName = $this->doUpload($control,LOGO_PATH,$image,'all'))
    {

    } else {

    }
}

config/constants.php << for the LOGO_PATH. Change these (and the name) to suit your purposes. The reasoning is if I ever change where I want to save images I change it in the constants rather than in 10 places throughout my application.

define('LOGO_PATH',APPPATH.'assets/images/manulogos/');
define('PROD_IMAGE_PATH',APPPATH.'../assets/images/prod_images/');
Rick Calder
  • 18,310
  • 3
  • 24
  • 41
  • I am getting error in if($imageName = $this->doUpload($control,LOGO_PATH,$image,'all')) line that " Use of undefined constant LOGO_PATH - assumed 'LOGO_PATH' " – Sahil Jariwala Oct 31 '12 at 11:09
  • Ahh forgot to mention that, I have my upload paths set as constants in my constants.php config file. You could just feed it your save path in that case. I do that so if I ever change the location of those I only have to change it in one place. I'll edit in the constants setting in a sec. – Rick Calder Oct 31 '12 at 11:22
  • ok.. i shall define $path as soon as the function addManufacturerLogo() begins. But should i pass logo as $logo or i need to define $logo? – Sahil Jariwala Oct 31 '12 at 11:41
  • yes it did worked. You code helped me reduce a lot of research work esp. including ajax. – Sahil Jariwala Oct 31 '12 at 11:48
3

Best is to use client side tools to resize the image locally, then upload. You can resize on the server side too (using php gd) but php copies the file in memory and by default, it can only resize images upto +/- 2MB. You can restrict uploading size and resize using php or you can use Flash, Silverlight or JavaApplets.

Here is another question about client side resizing using flash

UPDATE:

Example for serverside resize using CI's Image Manipulation lib

$config['image_library'] = 'gd2';
$config['source_image'] = $_FILES['image']['tmp_name'];
$config['new_image'] = $target_path
$config['maintain_ratio'] = TRUE;
$config['width']    = 250;
$config['height']   = 400;

$this->load->library('image_lib', $config); 

if (!$this->image_lib->resize()) {
    echo $this->image_lib->display_errors();
}

More info about the resizing lib

Community
  • 1
  • 1
VDP
  • 6,340
  • 4
  • 31
  • 53
  • i have already mentioned in my code $config['max_size'] = '1024'; and further i want this all to happen in my controller. The client is free to upload image as per my configuration rules that dines the maximum image size and allowed extension. I want my controller to resize it and when the resized image is uploaded it will appear in the different size then the orginial everywhere. – Sahil Jariwala Oct 31 '12 at 09:37
  • Yes, that is php == serverside. I quote "Now I want to resize image before uploading." => indicating client side resizing? Am I correct? – VDP Oct 31 '12 at 09:41
  • Ok ;)So you want it resized after uploading. I'll work something out. – VDP Oct 31 '12 at 09:42
  • yes.. see basically when the user will select image and click on the upload button. The image will be sent to controller. Now before the controller transfers the image to the uploads folder, the controller should resize and then transfer it to uploads folder in the server. By doing this whenever we are retrieving the image we don't need to resize it everytime. – Sahil Jariwala Oct 31 '12 at 09:44
  • thanks for the code. But this code doesnt upload the image. And the link is helpful. – Sahil Jariwala Oct 31 '12 at 10:42
  • You provided the uploading part yourself :) Here's the [docs](http://codeigniter.com/user_guide/libraries/file_uploading.html) about uploading – VDP Oct 31 '12 at 11:53