2

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
  • 55
  • 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

3

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.

This code was adapted from a snippet at FliquidStudios: Resizing images in PHP with GD and Imagick.

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."; 

}

?>
Herbert
  • 5,500
  • 2
  • 24
  • 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
  • Thanks Herbert, I really appreciate your help – Lucy Sep 26 '11 at 11:50
  • @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
  • @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
0

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
  • 16,471
  • 6
  • 54
  • 64