Forum Moderators: coopster
First of all i've VDS Server so i can change any settings in PHP or Apache so all comments are welcomed...
I am running a web site where users can upload images and its been online for 4 months and going well, but suddenly i discoverd that when uploading a picture that is about 1 MB 800x530 pixels or other which is 464 KB 1600x1200 pixels, then my script cant read their height and width then i get invalid dimensions and the image dont get resized at all and stays at their original width & height which breaks the page design!
and this is when i was using:
imagesx();
imagesy();
but i got the dimensions using "getimagesize()" and it was resized correctly but both images turned black!
So where could be the fail!
Please help me urgently because i think am losing users, i dono how come i didnt test big images b4 going live :(
Here is the part where the fail & warnings come!
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
{
$info = getimagesize($uploadfile);
$width = $info[0];
$height = $info[1];
$type = $info[2];
$attr = $info[3];
$image = "$uploadfile";
$newimage = "$uploadfile";
$image_quality = 75;
$addborder = 0;
$max_height = 480;
$max_width = 640;
// Main code
switch( $info['mime'] ){
case 'image/jpeg': $src_img = @imagecreatefromjpeg($image); break;
case 'image/gif' : $src_img = @imagecreatefromgif($image);
}
$orig_x = $width;
$orig_y = @imagesy($src_img);
if($width > 640 ¦¦ $height > 480)
{
$new_y = $max_height;
$new_x = $orig_x/($orig_y/$max_height);
if ($new_x > $max_width) {
$new_x = $max_width;
$new_y = $orig_y/($orig_x/$max_width);
}
$dst_img = @imagecreatetruecolor($new_x,$new_y);
@imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $new_x, $new_y, $orig_x, $orig_y);
}
else
{
$dst_img = @imagecreatetruecolor($width,$height);
@imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $width, $height, $orig_x, $orig_y);
}
@imagejpeg($dst_img, $newimage, $image_quality);
@imagedestroy($src_img);
@imagedestroy($dst_img);
$_SESSION["img"] = "$uploadfile";
$formVars["userfile"] = "$uploadfile";
$img = "$uploadfile";
if($width > 640 ¦¦ $height > 480)
{
$_SESSION["x"]="$new_x";
$_SESSION["y"]="$new_y";
}
else
{
$_SESSION["x"]="$width";
$_SESSION["y"]="$height";
}
}
Thanks in advance
if($_FILES['userfile']['name']!= '')
{
if($_FILES['userfile']['size'] > 7)
{
ob_start();
$directory = "upload/"; //directory name, where all the images upload
//show the upload file form
$uploaddir = $directory;
$trim = str_replace(" ", "",basename($_FILES['userfile']['name']));
$name = strtolower($trim);
srand((double)microtime()*1000000);
if(substr($name, -5, 5) == '.jpeg' ¦¦ substr($name, -5, 5) == '.JPEG' ¦¦ substr($name, -5, 5) == '.tiff' ¦¦ substr($name, -5, 5) == '.TIFF')
{
$number2 = rand(0,100000000) . substr($name, -5, 5);
}
else
{
$number2 = rand(0,100000000) . substr($name, -4, 4);
}
$uploadfile = $uploaddir . $number2;
if(substr($name, -5, 5) == '.jpeg' ¦¦ substr($name, -4, 4) == '.gif' ¦¦ substr($name, -4, 4) == '.jpg' ¦¦ substr($name, -5, 5) == '.JPEG' ¦¦ substr($name, -4, 4) == '.GIF' ¦¦ substr($name, -4, 4) == '.JPG')
{
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
{
$info = getimagesize($uploadfile);
$width = $info[0];
$height = $info[1];
$type = $info[2];
$attr = $info[3];
$image = "$uploadfile";
$newimage = "$uploadfile";
$image_quality = 75;
$addborder = 0;
$max_height = 480;
$max_width = 640;
// Main code
switch( $info['mime'] ){
case 'image/jpeg': $src_img = @imagecreatefromjpeg($image); break;
case 'image/gif' : $src_img = @imagecreatefromgif($image);
}
$orig_x = $width;
$orig_y = $height;
if($width > 640 ¦¦ $height > 480)
{
$new_y = $max_height;
$new_x = $orig_x/($orig_y/$max_height);
if ($new_x > $max_width) {
$new_x = $max_width;
$new_y = $orig_y/($orig_x/$max_width);
}
$dst_img = @imagecreatetruecolor($new_x,$new_y);
@imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $new_x, $new_y, $orig_x, $orig_y);
}
else
{
$dst_img = @imagecreatetruecolor($width,$height);
@imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $width, $height, $orig_x, $orig_y);
}
@imagejpeg($dst_img, $newimage, $image_quality);
@imagedestroy($src_img);
@imagedestroy($dst_img);
$_SESSION["img"] = "$uploadfile";
$formVars["userfile"] = "$uploadfile";
$img = "$uploadfile";
if($width > 640 ¦¦ $height > 480)
{
$_SESSION["x"]="$new_x";
$_SESSION["y"]="$new_y";
}
else
{
$_SESSION["x"]="$width";
$_SESSION["y"]="$height";
}
}
else
{
$errors["userfile"]="Din bild skcsikade inte, försok igen!";
$jer1.= "k";
}
}
else
{
$errors["userfile"]="Bilden måste vara en JPEG, JPG eller GIF";
$jer1.= "k";
}
}
else
{
$errors["userfile"]="Din bild existera inte";
$jer1.= "k";
}
}
else
{
if(isset($_POST["myimg"]))
{
$_SESSION["img"] = $_POST["myimg"];
}
}
}
First, remove all the "@" signs in front of your function calls. That character suppresses error messages -- error messages that might be useful to you when you must troubleshoot your script.
Next, at the top of your script, add error_reporting (you can later comment these lines out for when the code goes live):
ini_set("display_errors", "on");
error_reporting(E_ALL);
If that reveals any PHP error reporting, work through those issues and post back with any questions. :)
Added: Also, please add this line so you can see what values the script is working with.
$info = getimagesize($uploadfile);
[red][b]print_r($info);[/b][/red]
Here are the errors:
Warning: imagecopyresampled(): supplied argument is not a valid Image resource in /sitename/public_html/filename.php on line 383
Warning: imagedestroy(): supplied argument is not a valid Image resource in /sitename/public_html/filename.php on line 393
thanks in advance
so first 2 get resized but turns to black but the third works normally.
Both who turn to black are large in sizes and dimensions or at least bigger than width="640" height="480"
Turns to BLACK - 1.21 MB
Array ( [0] => 800 [1] => 530 [2] => 6 [3] => width="800" height="530" [bits] => 24 [mime] => image/bmp )
Turns to BLACK - 464 KB
Array ( [0] => 1600 [1] => 1200 [2] => 2 [3] => width="1600" height="1200" [bits] => 8 [channels] => 3 [mime] => image/jpeg )
Works fine - 85 KB
Array ( [0] => 640 [1] => 480 [2] => 2 [3] => width="640" height="480" [bits] => 8 [channels] => 3 [mime] => image/jpeg )
Do those errors only show up when the image ends up turning to black?
Added: "supplied argument is not a valid Image resource" is pretty much a guaranteed failure for GD stuff. It means the image buffer handle isn't valid, so the entire operation isn't occuring. I'd guess your $dst_image is being generated properly (since imagecreatetruecolor makes a black image by default) and the $src_image is failing.
Turns to BLACK - 1.21 MB
Array ( [0] => 800 [1] => 530 [2] => 6 [3] => width="800" height="530" [bits] => 24 [mime] => image/bmp )
This one is a good example of what I'm talking about... The mime/type is "image/bmp" and your switch statement for creating the $src_img image doesn't cover that mime type, so it will end up trying to copy a non-existent image onto a black background. BMP's will fail no matter what until you add an extra step to convert them to a GD supported format. Although this function [us2.php.net] isn't the correct one for BMP files, the comments are helpful.
As far as the JPEG failing, we're still working on that... :)
The simple way to set memory_limit is with a line like this:
ini_set( 'memory_limit', '32M' );
To test this theory, add that line and try a large jpeg image. Hopefully that will fix it and let us know the problem is a memory_limit problem.
However, for the actual script, setting memory_limit so high will result in a lot of wastage because some files won't need that much. There's a nice function to dynamically allocate memory based on the size and characteristics of the exact image available in the comments section of the PHP manual page for imagecreatefromjpeg [php.net]... look for the function named "setMemoryForImage" posted by a "e dot a dot schultz".
If so, the actual problem is on this line, since this line is failing to do it's job:
case 'image/jpeg': $src_img = imagecreatefromjpeg($image); break;
If memory is sufficient to the task, the next thing to check is max_execution_time (and affect it with set_time_limit [php.net]). Here's a page on the PHP manual about Common Pitfalls for PHP File Uploads [us2.php.net] that should be of help.
I was trying with 3 images 2 of them didnt open with photoshop, it said invalid images..
The third opend so i saved it at highest resolution so it was 1 mega with dimensions 1600x1200 and it worked out well! ;)
Thanks
but just to end this i want usefull information!
if a user is trying to upload very big picture, i dono what is the biggest dimensions available or biggest sizes could be, but lets say 10Mega jpeg image.. how much memory would that need?
Thanks a lot
how much memory would that need?
I would use the function I reference a few posts back to dynamically allocate a sufficient amount based on the image characteristics. Look for the function named "setMemoryForImage" posted by a "e dot a dot schultz" on this page: [php.net...]
$K64 = 65536; // number of bytes in 64K
$TWEAKFACTOR = 1.5; // Or whatever works for you
$memoryNeeded = round( ( $imageInfo[0] * $imageInfo[1]
* $imageInfo['bits']
* $imageInfo['channels'] / 8
+ $K64
) * $TWEAKFACTOR
);
Let's assume your 464 KB 1600x1200 JPEG from above is the input, the memory needed would be around 8.8 MB. So, in most cases a memory limit of 16MB to 24MB would be plenty.