3

I've got a script that uploads files to the server as well as adds the filename to a database, but what I'd like to do it restrict the maximum dimensions of the image before uploading. So if I upload an image that is 1000 x 500 it will be restricted but still keep it's dimensions and will be changed to 200 x 100, but an image that is 300 x 300 will be restricted to 200 x 200

    <?php 

     //This is the directory where images will be saved 
     $target = "uploads/"; 
     $target = $target . basename( $_FILES['photo']['name']); 

     //This gets all the other information from the form 
     $name=$_POST['name']; 
     $pic=($_FILES['photo']['name']); 

     // Connects to your Database 
     mysql_connect("hostname", "username", "password") or die(mysql_error()) ; 
     mysql_select_db("database") or die(mysql_error()) ; 

     //Writes the information to the database 
     mysql_query("INSERT INTO `table` (name, photo) VALUES ('$name','$pic')") ; 

     //Writes the photo to the server 
     if(move_uploaded_file($_FILES['photo']['tmp_name'], $target)) 
     { 

     //Tells you if its all ok 
     echo "The file ". basename( $_FILES['uploadedfile']['name']). " has been uploaded"; 
     } 
     else { 

     //Gives and error if its not 
     echo "Sorry, there was a problem uploading your file."; 
     } 
     ?> 

Thanks for your help

Lucy
  • 65
  • 2
  • 9
  • As it stands, this is a "write my code for me" request, not a question. – Pekka Sep 26 '11 at 09:43
  • What have you tried so far ? On what part are you stuck ? Also, please do not use $_POST data straight up inside an sql query like that, this is a huge security flaw ... See this question for [explanations](http://stackoverflow.com/questions/60174/best-way-to-stop-sql-injection-in-php) – Lepidosteus Sep 26 '11 at 09:44
  • 1
    Make files smaller before(!) upload has nothing to do with PHP, MySQL or something similar – rabudde Sep 26 '11 at 09:58
  • Sorry I didn't realise about $_POST should I use $_GET instead? I'm very new to php so am not that sure about everything. I've searched google for code that resizes the images before upload, but I can't work out how to integrate it with the code I've already got. – Lucy Sep 26 '11 at 10:05
  • @Lucy it's a security flaw because whatever the user puts in the form will uploaded to the database; have a read of [this article](http://php.net/manual/en/security.database.sql-injection.php) (or Google 'sql injection'); in essence, you should escape all characters before uploading them to the database; this is done most easily by using PHP's `mysql_real_escape_string()` function – ChrisW Sep 26 '11 at 10:35

2 Answers2

4

To my knowledge, you can’t resize the image before uploading it. (I could be wrong!) However, when you upload the image it goes into a temporary file. You can resize the temporary image and copy the resized image to its final destination.

Since (it seems) you want to keep the width constant, you don’t really need to do a lot of ratio tests.

Update:

You should be able to simply use this in place of your original code. Most of it is unchanged.

<?php

// resizes an image to fit a given width in pixels.
// works with BMP, PNG, JPEG, and GIF
// $file is overwritten
function fit_image_file_to_width($file, $w, $mime = 'image/jpeg') {
    list($width, $height) = getimagesize($file);
    $newwidth = $w;
    $newheight = $w * $height / $width;
    
    switch ($mime) {
        case 'image/jpeg':
            $src = imagecreatefromjpeg($file);
            break;
        case 'image/png';
            $src = imagecreatefrompng($file);
            break;
        case 'image/bmp';
            $src = imagecreatefromwbmp($file);
            break;
        case 'image/gif';
            $src = imagecreatefromgif($file);
            break;
    }
    
    $dst = imagecreatetruecolor($newwidth, $newheight);
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
    
    switch ($mime) {
        case 'image/jpeg':
            imagejpeg($dst, $file);
            break;
        case 'image/png';
            imagealphablending($dst, false);
            imagesavealpha($dst, true);
            imagepng($dst, $file);
            break;
        case 'image/bmp';
            imagewbmp($dst, $file);
            break;
        case 'image/gif';
            imagegif($dst, $file);
            break;
    }
    
    imagedestroy($dst);
}

// init file vars
$pic  = $_FILES['photo']['name'];
$target = 'uploads/' . basename( $_FILES['photo']['name']);
$temp_name = $_FILES['photo']['tmp_name'];
$type = $_FILES["photo"]["type"];

// Connects to your Database 
mysql_connect("hostname", "username", "password") or die(mysql_error()) ; 
mysql_select_db("database") or die(mysql_error()) ; 

// get form data
$name = mysql_real_escape_string(isset($_POST['name']) ? $_POST['name'] : 'No name');

//Writes the information to the database 
mysql_query("INSERT INTO `table` (name, photo) VALUES ('$name','$pic')") ; 

// resize the image in the tmp directorys
fit_image_file_to_width($temp_name, 200, $type);

//Writes the photo to the server
if(move_uploaded_file($temp_name, $target)) {

    //Tells you if its all ok 
    echo "The file ". basename( $_FILES['photo']['name'] ). " has been uploaded"; 

} else {

    //Gives and error if its not 
    echo "Sorry, there was a problem uploading your file."; 

}

?>
Mr Noob
  • 116
  • 2
  • 10
Herbert
  • 5,698
  • 2
  • 26
  • 34
  • Thanks for that, I did try it and it looks like what I'm after, but when I tested it nothing happened. I might have added the code to mine wrongly though. Should I use your code instead of the code I was originally using, or should I add you code to mine? Sorry for the dumb questions, I'm very new to PHP – Lucy Sep 26 '11 at 11:00
  • @Lucy: First, the only dumb question is the one you don't ask. :) I updated the answer so you _should_ be able to use my code in place of yours. – Herbert Sep 26 '11 at 11:19
  • Thanks for helping me with this. I tried your new code, but nothing happened at all. I didbn't get any errors - just a blank page and nothing in the database :( – Lucy Sep 26 '11 at 11:24
  • There's a typo that I overlooked. I'm working on debugging it so bare with me. :-). – Herbert Sep 26 '11 at 11:34
  • @Lucy: Okay, I tested everything but the database related code and had no problems. I tested it with 2 JPEG files and a PNG file, portrait (tall and narrow), landscape (short and wide), and square images. It'll support BMP and GIF as well. Don't forget to change your db variables (hostname, username, etc.). – Herbert Sep 26 '11 at 13:09
  • Wonderful, thank you so much. I guess I want to change the dimensions at anytime I can just change 'fit_image_file_to_width($temp_name, 200, $type);' to what ever width? Seriously though, thank you. It's really kind of you to help me. – Lucy Sep 27 '11 at 14:36
  • 1
    @Lucy: You're quite welcome. Yes, you can just change the width. Better still, you can assign the width to a constant/variable at the top of your script. Btw: It's customary on Stack Overflow to accept an answer that helps you by clicking the big check mark to the side of the answer. :-) – Herbert Sep 27 '11 at 15:37
1

I used in the past this function to generate thumbnails that fit in given dimensions keeping aspect ratio, maybe you can use it somehow:

function resize_img_nofill($src_name,$dst_name,$width,$height,$dontExpand=false) {
        $MAGIC_QUOTES = set_magic_quotes_runtime();
        set_magic_quotes_runtime(0);

        $type =  strtolower(substr(strrchr($src_name,"."),1));

        if($type == "jpg") {
            $src = imagecreatefromjpeg($src_name);
        } else if($type == "png") {
            $src = imagecreatefrompng($src_name);    
        } else if($type == "gif") {
            $src = imagecreatefromgif($src_name);    
        } else {
                if($src_name != $dst_name) copy($src_name,$dst_name);
                set_magic_quotes_runtime($MAGIC_QUOTES);
                return;
        }



        $d_width = $s_width = imagesx($src);
        $d_height = $s_height = imagesy($src);

        if($s_width*$height > $width*$s_height && (!$dontExpand || $width < $s_width)) {
            $d_width = $width;
            $d_height = (int)round($s_height*$d_width/$s_width);
        } else if(!$dontExpand || $height < $s_height) {
            $d_height = $height;
            $d_width = (int)round($s_width*$d_height/$s_height);
        }

        if($s_width != $d_width || $s_height != $d_height) {

                if($type == "jpg") {
                        $dst = imagecreatetruecolor($d_width,$d_height);
                } else if($type == "png") {
                $dst = imagecreate($d_width,$d_height);
                } else if($type == "gif") {
                $dst = imagecreate($d_width,$d_height);
                } 

                $white = imagecolorallocate($dst,255,255,255);
                imagefilledrectangle($dst,0,0,$d_width,$d_height,$white);
                imagecopyresampled($dst,$src,0,0,0,0,$d_width,$d_height,$s_width,$s_height);

                if($type == "jpg") 
                imagejpeg($dst,$dst_name, 80);  
                else if($type == "png")
                imagepng($dst,$dst_name);       
                else if($type == "gif")
                imagegif($dst,$dst_name);       

                imagedestroy($dst);
                imagedestroy($src);
        } else {
                copy($src_name,$dst_name);
        }


        set_magic_quotes_runtime($MAGIC_QUOTES);
        return array($d_width,$d_height);
}
Kamil Szot
  • 17,436
  • 6
  • 62
  • 65