Client-side resizing / image uploader

I currently have radupload installed on my site to allow my site users to upload images to the server. It uses javascript and allows client-side resizing of images. When it works, it's great. However, it does not work for about half of my users. I'm wondering if there's a better product / code I could integrate into my forms that would be more robust.

I saw this one, which looks pretty good, but so far is not functioning as promised and customer support is not replying to my inquiries: http://www.resize-before-upload.com/download/

Does anyone have any suggestions for me? I am definitely willing to pay for the license for a code that will work for me.

Thanks!
maxbookAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

maxbookAuthor Commented:
Oh, I should add that this is what I need to be able to do:

- resize image client-side and upload to server with dynamically defined file name (my PHP code defines the file name based in item id, etc.)
- definable image compression and dimensions
- nice interface for user (drag and drop or browse with thumbnails)
- non-java preferred -- maybe something using flash would be more robust?
0
Ray PaseurCommented:
I can show you how to resize an image on the server side.  In my experience it is a more dependable process.  There are too many uncontrollable variables on the client side of things.  Here are two examples from my teaching library (Sorry, I can't remember which is more current, but I think it is the first one).
<?php // RAY_upload_resize_example.php
error_reporting(E_ALL);


// UPLOAD AN IMAGE AND RESIZE IT TO FIT SOME PREDEFINED SIZES
// http://php.net/manual/en/ref.image.php
// http://php.net/manual/en/features.file-upload.php
// http://php.net/manual/en/features.file-upload.common-pitfalls.php
// http://php.net/manual/en/function.move-uploaded-file.php
// http://php.net/manual/en/function.getimagesize.php
// http://php.net/manual/en/function.imagejpeg.php


// A FUNCTION TO DETERMINE IF GD IS AT LEVEL 2 OR MORE
function get_gd_info($display=FALSE)
{

    // IS GD INSTALLED AT ALL?
    if (!function_exists("gd_info"))
    {
        if ($display) echo "<br/>GD NOT INSTALLED\n";
        return FALSE;
    }

    // IF GD IS INSTALLED GET DETAILS
    $gd = gd_info();

    // IF DISPLAY IS REQUESTED, PRINT DETAILS
    if ($display)
    {
        echo "<br/>GD DETAILS:\n";
        foreach ($gd as $key => $value)
        {
            if ($value === TRUE)  $value = 'YES';
            if ($value === FALSE) $value = 'NO';
            echo "<br/>$key = $value \n";
        }
    }

    // RETURN THE VERSION NUMBER
    $gd_version = preg_replace('/[^0-9\.]/', '', $gd["GD Version"]);
    return $gd_version;
}


// A FUNCTION TO MAKE AN IMAGE INTO THE RIGHT WIDTH FOR PAGE DISPLAY
// WILL WORK IF GD2 NOT INSTALLED, BUT WILL MAKE BETTER IMAGES WITH GD2
// INPUT IS THE IMAGE FILE NAME, OUTPUT IS AN IMAGE RESOURCE, OR FALSE IF NO RESIZE NEEDED
function create_right_size_image($image, $width=720)
{
    // IS GD HERE?
    $gdv = get_gd_info();
    if (!$gdv) return FALSE;

    // GET AN IMAGE THING
    $source = imagecreatefromjpeg("$image");

    // GET THE X AND Y DIMENSIONS
    $imageX = imagesx($source);
    $imageY = imagesy($source);

    // IF NO RESIZING IS NEEDED
    if ($imageX <= $width)
    {
        return FALSE;
    }

    // THE WIDTH IS TOO GREAT - MUST RESIZE
    $tnailX = $width;
    $tnailY = (int) (($tnailX * $imageY) / $imageX );

    // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
    if ($gdv >= 2)
    {
        // IF GD IS AT LEVEL 2 OR ABOVE
        $target = imagecreatetruecolor($tnailX, $tnailY);
        imagecopyresampled ($target, $source, 0, 0, 0, 0, $tnailX, $tnailY, $imageX, $imageY);
    }
    else
    {
        // IF GD IS AT A LOWER REVISION LEVEL
       $target = imagecreate($tnailX, $tnailY);
       imagecopyresized   ($target, $source, 0, 0, 0, 0, $tnailX, $tnailY, $imageX, $imageY);
    }
    return $target ;
}
/* ********************************************************************************************* */


// ESTABLISH THE NAMES OF THE DIRECTORIES
$s = 'RAY/storage/';
$p = 'RAY/pics/';
$t = 'RAY/thumbs/';

// ESTABLISH THE LARGEST FILE WE WILL UPLOAD
$max_file_size = '5000000'; // A BIT MORE THAN 4MB

// THIS IS A LIST OF THE POSSIBLE ERRORS THAT CAN BE REPORTED in $_FILES[]["error"]
$errors = array
( 0 => "Success!"
, 1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, 2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, 3 => "The uploaded file was only partially uploaded"
, 4 => "No file was uploaded"
, 5 => "UNDEFINED"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;

// IF THERE IS INFORMATION POSTED
if (!empty($_POST))
{
    // IF THERE ARE ERRORS
    $error_code    = $_FILES["userfile"]["error"];
    if ($error_code)
    {
        die($errors[$error_code]);
    }

    // SYNTHESIZE THE NEW FILE NAME FOR TEMPORARY STORAGE
    $f = basename($_FILES['userfile']['name']);
    $my_new  = getcwd() . '/' . $s . $f;
    $my_temp =                  $s . $f;

    // MOVE THE FILE INTO THE STORAGE DIRECTORY
    if (!move_uploaded_file($_FILES['userfile']['tmp_name'], $my_new))
    {
        die("MOVE TO $my_new FAILED");
    }

    // SAVE THE PIC
    if ($image_resource = create_right_size_image($my_temp, 450))
    {
        imagejpeg($image_resource, $p . $f);
        imagedestroy($image_resource);
    }

    // SAVE THE THUMB
    if ($image_resource = create_right_size_image($my_temp, 100))
    {
        imagejpeg($image_resource, $t . $f);
        imagedestroy($image_resource);
    }

    // DISPOSE OF THE UNWANTED ORIGINAL
    unlink($my_new);

    // SHOW THE LINKS TO THE NEW FILES
    echo '<br/><a href="' . $p . $f . '">PIC</a>';
    echo '<br/><a href="' . $t . $f . '">THUMB</a>';
}


// CREATE THE FORM FOR INPUT (USING HEREDOC SYNTAX)
$form = <<<ENDFORM
<form enctype="multipart/form-data" method="post">
<!-- MAX_FILE_SIZE MUST PRECEDE THE FILE INPUT FIELD -->
<input type="hidden" name="MAX_FILE_SIZE" value="$max_file_size" />
Find a Photo to Upload: <input name="userfile" type="file" />
<input type="submit" value="Upload" />
</form>
ENDFORM;

echo $form;

Open in new window

<?php // RAY_upload_and_resize_image.php
date_default_timezone_set('America/Chicago');


// UPLOAD AN IMAGE AND RESIZE IT TO FIT A PREDEFINED SIZE


// A FUNCTION TO DETERMINE IF GD IS AT LEVEL 2 OR MORE
function get_gd_info($display=FALSE)
{

    // IS GD INSTALLED AT ALL?
    if (!function_exists("gd_info"))
    {
        if ($display) echo "<br/>GD NOT INSTALLED\n";
        return FALSE;
    }

    // IF GD IS INSTALLED GET DETAILS
    $gd = gd_info();

    // IF DISPLAY IS REQUESTED, PRINT DETAILS
    if ($display)
    {
        echo "<br/>GD DETAILS:\n";
        foreach ($gd as $key => $value)
        {
            if ($value === TRUE)  $value = 'YES';
            if ($value === FALSE) $value = 'NO';
            echo "<br/>$key = $value \n";
        }
    }

    // RETURN THE VERSION NUMBER
    $gd_version = preg_replace('/[^0-9\.]/', '', $gd["GD Version"]);
    return $gd_version;
}


// A FUNCTION TO MAKE AN IMAGE INTO THE RIGHT WIDTH FOR PAGE DISPLAY
// WILL WORK IF GD2 NOT INSTALLED, BUT WILL MAKE BETTER IMAGES WITH GD2
// INPUT IS THE IMAGE FILE NAME, OUTPUT IS AN IMAGE RESOURCE, OR FALSE IF NO RESIZE NEEDED
function create_right_size_image($image, $width=720)
{
    // IS GD HERE?
    $gdv = get_gd_info();
    if (!$gdv) return FALSE;

    // GET AN IMAGE THING
    $source = imagecreatefromjpeg("$image");

    // GET THE X AND Y DIMENSIONS
    $imageX = imagesx($source);
    $imageY = imagesy($source);

    // IF NO RESIZING IS NEEDED
    if ($imageX <= $width)
    {
        return FALSE;
    }

    // THE WIDTH IS TOO GREAT - MUST RESIZE
    $tnailX = $width;
    $tnailY = (int) (($tnailX * $imageY) / $imageX );

    // WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
    if ($gdv >= 2)
    {
        // IF GD IS AT LEVEL 2 OR ABOVE
        $target = imagecreatetruecolor($tnailX, $tnailY);
        imagecopyresampled ($target, $source, 0, 0, 0, 0, $tnailX, $tnailY, $imageX, $imageY);
    } else
    {
        // IF GD IS AT A LOWER REVISION LEVEL
       $target = imagecreate($tnailX, $tnailY);
       imagecopyresized   ($target, $source, 0, 0, 0, 0, $tnailX, $tnailY, $imageX, $imageY);
    }
    return $target ;
}
/* ********************************************************************************************* */


// ESTABLISH THE NAME OF THE PHOTOS DIRECTORY
$photos    = 'RAY_junk';

// ESTABLISH THE LARGEST FILE WE WILL UPLOAD
$max_file_size = '5000000'; // A BIT MORE THAN 4MB

// THIS IS A LIST OF THE POSSIBLE ERRORS THAT CAN BE REPORTED in $_FILES[]["error"]
$errors = array
( 0 => "Success!"
, 1 => "The uploaded file exceeds the upload_max_filesize directive in php.ini"
, 2 => "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
, 3 => "The uploaded file was only partially uploaded"
, 4 => "No file was uploaded"
, 5 => "UNDEFINED"
, 6 => "Missing a temporary folder"
, 7 => "Cannot write file to disk"
)
;

// IF THERE IS NOTHING USEFUL IN $_POST, PUT UP THE FORM FOR INPUT
if ( (empty($_POST['p'])) && (empty($_POST['MAX_FILE_SIZE'])) ) {
    ?>
    <h2>Upload Photos</h2>

    <!-- NOTE THE USE OF ENCTYPE -->
    <form name="UploadForm" enctype="multipart/form-data" action="<?=$_SERVER["REQUEST_URI"]?>" method="POST">
    <input type="hidden" name="p" value="1" />
    <!-- MAX_FILE_SIZE MUST PRECEDE THE FILE INPUT FIELD -->
    <input type="hidden" name="MAX_FILE_SIZE" value="<?=$max_file_size?>" />
    <!-- INPUT NAME= IN TYPE=FILE DETERMINES THE NAME FOR ACTION SCRIPT TO USE IN $_FILES ARRAY -->
    <p>
    Find the photo you want to upload and click the "Upload" button below.
    </p>

    <table cellpadding="1" cellspacing="1" border="0">
    <tr><td align="right"><span class="required">Photo: </span></td> <td><input name="userfile" type="file" size="80" /></td></tr>
    <tr><td> </td><td><input type="submit" name="_submit" value="Upload" />
    &nbsp; &nbsp; Check this box <input autocomplete="off" type="checkbox" name="overwrite" /> to <b>overwrite</b> an existing photo.</td></tr>
    </table>
    </form>

    <?php die();

}

// THERE IS POST DATA - PROCESS IT
else
{
    echo "<h2>Results: Upload Photos</h2>\n";
    echo "<p>\n";

    // SYNTHESIZE THE NEW FILE NAME
    $f_type  = trim(strtolower(end    (explode( '.', basename($_FILES['userfile']['name'] )))));
    $f_name  = trim(strtolower(current(explode( '.', basename($_FILES['userfile']['name'] )))));
    $my_new  = getcwd() . '/' . $photos . '/' . $f_name . '.' . $f_type;
    $my_file = $photos  . '/' . $f_name . '.' . $f_type;

    // TEST FOR ALLOWABLE EXTENSIONS (ADD OTHERS AS NEEDED)
    if ($f_type != 'jpg')
    {
        die('Sorry, only JPG files allowed');
    }

    // IF THERE ARE ERRORS
    $error_code    = $_FILES["userfile"]["error"];
    if ($error_code != 0)
    {
        $error_message = $errors[$error_code];
        echo "<p class=\"required\">Upload Error Code: $error_code: $error_message</p>\n";
        die('Sorry');
    }

    // MOVE THE FILE INTO THE DIRECTORY
    $overwrite    = $_POST['overwrite'];
    $file_size    = number_format($_FILES["userfile"]["size"]);

    // IF THE FILE IS NEW
    if (!file_exists($my_new))
    {
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $my_new))
        {
            $upload_success = 1;
        }
        else
        {
            $upload_success = -1;
        }
    }
    // IF THE FILE ALREADY EXISTS
    else
    {
        echo "<b><i>$my_file</i></b> already exists.\n";

        // SHOULD WE OVERWRITE THE FILE? IF NOT
        if (empty($overwrite))
        {
            $upload_success = 0;
        }
        // IF WE SHOULD OVERWRITE THE FILE, TRY TO MAKE A BACKUP
        else
        {
            $now    = date('Y-m-d');
            $my_bak = $my_new . '.' . $now . '.bak';
            if (!copy($my_new, $my_bak))
            {
                echo "<b>Attempted Backup Failed!</b>\n";
            }
            if (move_uploaded_file($_FILES['userfile']['tmp_name'], $my_new))
            {
                $upload_success = 2;
            }
            else
            {
                $upload_success = -1;
            }
        }
    }

    // REPORT OUR SUCCESS OR FAILURE
    if ($upload_success == 2) { echo "It has been overwritten.\n"; }
    if ($upload_success == 1) { echo "<b><i>$my_file</i></b> has been saved.\n"; }
    if ($upload_success == 0) { echo "<b>It was NOT overwritten.</b>\n"; }

    if ($upload_success > 0)
    {
        echo "$file_size bytes uploaded.\n";
        chmod ($my_new, 0755);
    }

    echo "</p>\n";

    // RESIZE THE FILE TO FIT DESIGNATED WIDTH, IF NECESSARY
    if ($upload_success > 0)
    {
        if ($imageblob = create_right_size_image($my_new))
        {
            imagejpeg($imageblob, $my_new);
        }
    }

    echo "<p><a href=\"$my_file\">See the file</a></p>\n";
}

Open in new window


These are just teaching examples.  You can copy the code, install it on your own server and run it, but you might want to make some changes to integrate it more closely into your scripts.  Just follow the design patterns and you should be fine.

HTH, ~Ray
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Michel PlungjanIT ExpertCommented:
Have a look at uploadify
0
maxbookAuthor Commented:
Ray -- thanks. I do have a server-side upload option, but it is pretty resource intensive. Especially with people trying to upload their 5 Mb photos these days.

mplungian -- thanks, I'll take a look at it.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Scripting Languages

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.