PHP - Upload Large Images - Resizing

software development

#1

Greetings,

I have a feature on our site where members can upload up to 5 images at one time. I have set the maximum image size to 250kb.

Unfortunately, many members have complained because they take pictures on 10 Megapixel cameras and are unable to upload the raw images (10 Megabytes) because they are too big. I know Facebook and other places can deal with this, so I need help in effectively doing this.

I found out these stats in the Dreamhost php.ini file
memory limit = 90M
post_max_size = 8M
upload_max_filesize = 7M

Am I able to alter these maximum figures? If not and if a person uploads 5 images of the same size at one time, what would be the maximum filesize of each one allowed?

Finally, how can I resize these images with PHP to something like 250kb so they don’t take up 1MB to 10MB of disk space per image, yet keep much of the same quality to a practical level?


#2

Use either PHP’s ini_set() function or the .htaccess file. memory_limit can be set using ini_set() but post_max_size and upload_max_filesize need to use the .htaccess.

Some other links that may be helpful:
[list]
[]php.ini directives
[
]Where configuration settings may be set
[/list]


#3

sXi has a great script to help with this. You only need to increase post_max_size and upload_max_filesize.

Imagemagick is good for resizing images:


#4

Hello,

Thanks for the responses. I was able to find a really simple script that works great up to a point.

When someone uploads a random 4000x3000 picture (one was 3.8MB and another 2.9MB in my tests), I get this error:
Fatal error: Allowed memory size of 94371840 bytes exhausted (tried to allocate 16000 bytes)

I also tried adding this (php_value memory_limit 164M) to my .htaccess file to add more than 90MB, but I got the same error as above. I’m not sure if the values set by Dreamhost are in stone or if I’m doing it wrong.

I’m not very familiar with image uploading and memory issues. Is my 90MB limit based on the actual dimensions of the image (4000x3000) or is it related to the file size (3.8MB or 2.9MB)? Based on the Dreamhost memory and upload size limits, what is the maximum size image that I can allow people to upload without problems?

(My goal is to allow anyone with any Megapixel camera to be able to upload any sized raw image without manually having to shrink it down, but also produce the least amount of strain on the server and use the least amount of disk space possible, hopefully by either reducing the quality of the image or the physical dimensions in order to compress it.)


#5

Maybe something like this instead?

http://demo.swfupload.org/v250beta3/resizedemo/index.php


#6

That looks like a very interesting tool. Do you know how to display 5 upload fields and also alter the final size of the photo?


#7

I was looking at that tool and I think it is too complicated to me since I do not know JavaScript as well as I do with PHP.

I am very close to figuring out exactly what I need but there is some errors. I let users upload 5 images at one time which each image having a maximum upload size of 1MB.

If I have 5 images that are less than 1 MB each, I still get the error: “Fatal error: Allowed memory size of 94371840 bytes exhausted (tried to allocate 2917 bytes)”

These are my Dreamhost php.ini settings and they seem to suggest that this upload should not be a problem:

memory limit = 90M
post_max_size = 8M
upload_max_filesize = 7M

Here is the entire code for my page (php and html form), maybe someone can take a look at this and find out what I can do to optimize and get this to work properly. I have been trying to use “imagedestroy()” but I’m not sure if this is having any effect:

CODE:

[php]

Image Test

Image Test:

<?php if(isset($_POST['submit'])){

################################################ PROCESSOR #################################################################################
// filename: upload.processor.php

// first let’s set some variables

// make a note of the current working directory, relative to root.
$directory_self = str_replace(basename($_SERVER[‘PHP_SELF’]), ‘’, $_SERVER[‘PHP_SELF’]);

// make a note of the directory that will recieve the uploaded files
$uploadsDirectory = $_SERVER[‘DOCUMENT_ROOT’] . $directory_self . ‘test/’;

// make a note of the location of the upload form in case we need it
$uploadForm = ‘http://’ . $_SERVER[‘HTTP_HOST’] . $directory_self . ‘multiple.upload.form.php’;

// make a note of the location of the success page
$uploadSuccess = ‘http://’ . $_SERVER[‘HTTP_HOST’] . $directory_self . ‘multiple.upload.success.php’;

// name of the fieldname used for the file in the HTML form
$fieldname = ‘file’;

//echo’

’;print_r($_FILES);exit;

// Now let’s deal with the uploaded files

// possible PHP upload errors
$errors = array(1 => ‘php.ini max file size exceeded’,
2 => ‘image file max size exceeded’,
3 => ‘file upload was only partial’,
4 => ‘no file was attached’);

// check the upload form was actually submitted else print form
isset($_POST[‘submit’])
or error(‘the upload form is neaded’, $uploadForm);

// check if any files were uploaded and if
// so store the active $_FILES array keys
$active_keys = array();
foreach($_FILES[$fieldname][‘name’] as $key => $filename)
{
if(!empty($filename))
{
$active_keys[] = $key;
}
}

// check at least one file was uploaded
//count($active_keys)
// or error(‘No files were uploaded’, $uploadForm);

// check for standard uploading errors
foreach($active_keys as $key)
{
($_FILES[$fieldname][‘error’][$key] == 0)
or error($_FILES[$fieldname][‘tmp_name’][$key].’: '.$errors[$_FILES[$fieldname][‘error’][$key]], $uploadForm);
}

// check that the file we are working on really was an HTTP upload
foreach($active_keys as $key)
{
@is_uploaded_file($_FILES[$fieldname][‘tmp_name’][$key])
or error($_FILES[$fieldname][‘tmp_name’][$key].’ not an HTTP upload’, $uploadForm);
}

// validation… since this is an image upload script we
// should run a check to make sure the upload is an image
foreach($active_keys as $key)
{
@getimagesize($_FILES[$fieldname][‘tmp_name’][$key])
or error($_FILES[$fieldname][‘tmp_name’][$key].’ not an image’, $uploadForm);
}

// make a unique filename for the uploaded file and check it is
// not taken… if it is keep trying until we find a vacant one
foreach($active_keys as $key)
{
$now = time();
while(file_exists($uploadFilename[$key] = $now.’-’.$_FILES[$fieldname][‘name’][$key]))
{
$now++;
}
}

foreach($active_keys as $key)
{
$nameparts = pathinfo($uploadFilename[$key]);
$extension = $nameparts[‘extension’];
$uploadFilename[$key] = substr($uploadFilename[$key],"", -4);
$uploadFilename[$key] = preg_replace(’/[^a-zA-Z0-9]/’, ‘-’, $uploadFilename[$key]);
$uploadFilename[$key] = $uploadFilename[$key].".".$extension;
}

// now let’s move the file to its final and allocate it with the new filename
foreach($active_keys as $key)
{
//$uploadFilename = preg_replace(’/[^a-zA-Z0-9]/’, ‘_’, $uploadFilename);
move_uploaded_file($_FILES[$fieldname][‘tmp_name’][$key], $_SERVER[‘DOCUMENT_ROOT’] . $directory_self . ‘test/’ . $uploadFilename[$key]) or error(‘receiving directory insuffiecient permission’, $uploadForm);
$imgfile = “test/”.$uploadFilename[$key];

list($width,$height)=getimagesize($imgfile);
/* The width and the height of the image also the getimagesize retrieve other information as well   */
echo "Width: ".$width."<br>";
echo "Height: ".$height."";
if ($width > $height) {$thumbsize = $width;} else {$thumbsize = $height;}
$imgratio=$width/$height; 
/*
To compress the image we will calculate the ration 
For eg. if the image width=700 and the height = 921 then the ration is 0.77...
if means the image must be compression from its height and the width is based on its height
so the newheight = thumbsize and the newwidth is thumbsize*0.77...
*/

if($imgratio>1) {
    $newwidth=$thumbsize;
    $newheight=$thumbsize/$imgratio;
} else {
    $newheight=$thumbsize;       
    $newwidth=$thumbsize*$imgratio;
}

$thumb=imagecreatetruecolor($newwidth,$newheight); // Making a new true color image
$source=imagecreatefromjpeg("test/".$uploadFilename[$key]); // Now it will create a new image from the source
imagecopyresampled($thumb,$source,0,0,0,0,$newwidth,$newheight,$width,$height);  // Copy and resize the image
imagejpeg($thumb,"test2/".$uploadFilename[$key],25);
imagedestroy($thumb);
imagedestroy($source);
echo "<span class='pass'>Original Image:</span><br>".$uploadFilename[$key]."<br>
<img src='test/".$uploadFilename[$key]."' />"; 
echo "<br><br><span class='pass'>New Image:</span><br>".$uploadFilename[$key]."<br>
<img src='test2/".$uploadFilename[$key]."' />"; 

}

// If you got this far, everything has worked and the file has been successfully saved.
// make an error handler which will be used if the upload fails
function error($error, $location, $seconds = 5)
{
echo ‘’."\n\n".
’’."\n".
’ ‘."\n".
’ ‘."\n\n".
’ ‘."\n\n".
’ Upload error’."\n\n".
’ ‘."\n\n".
’ ‘."\n\n".

‘."\n\n".

Upload failure

’."\n\n".

An error has occured ‘."\n\n".
’ . $error . ‘…’."\n\n".
’ Please press Back Button to retrieve form data and try again.

’."\n\n".
‘."\n\n".
’’;
exit;
} // end error handler
######################################################################################################################################################

} ?>

</center>
<div class="form">
  <form action="" method="post" name="add" id="add" enctype="multipart/form-data">
    <input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
    <table width="90%" border="0" cellpadding="3" cellspacing="1" bgcolor="#FFFFFF" class="form">
      <tr>

        <td>Images: (MAX UPLOAD 1MB)</td>
      </tr>
      <tr>
        <td>Image 1:
          <input id="image1" type="file" name="file[]" /></td>
      </tr>
      <tr>
        <td>Image 2:
          <input id="image2" type="file" name="file[]" /></td>
      </tr>
      <tr>
        <td>Image 3:
          <input id="image3" type="file" name="file[]" /></td>
      </tr>
      <tr>
        <td>Image 4:
          <input id="image4" type="file" name="file[]" /></td>
      </tr>
      <tr>
        <td>Image 5:
          <input id="image5" type="file" name="file[]" />
          <br />
          <br />
        <br /></td>
      </tr>
      <tr>
        <td><center>
            <input type="submit" name="submit" value="submit" />
          </center></td>
      </tr>
    </table>
  </form>
</div>
[/php]

#8

I just thought I would let everyone know that I solved the problem and just set my maximum image upload size to 1MB for JPG,GIF,PNG images. Then I just reduced the quality of all JPG images to ‘50’ to save more space. Hopefully most members do not need to use images this large and that this doesn’t take up too much space and memory.