4

I use following code to upload, rename, compress, create thumbnail everything works fine, And recently i noticed while creating thumb it creates fresh copy of thumb images for previously uploaded images also(create thumbnail for uploaded and uploading images too)

Problem:

When form is submitted it crates thumb for uploading image and uploaded images(image file that are present in older).

how do i solve this problem

if (!empty($_POST)) {
    if (isset($_FILES['files'])) {
        $uploadedFiles = array();
        foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name) {
            $errors = array();
            $file_name = md5(uniqid("") . time());
            $file_size = $_FILES['files']['size'][$key];
            $file_tmp = $_FILES['files']['tmp_name'][$key];
            $file_type = $_FILES['files']['type'][$key];
            if ($file_type == "image/gif") {
                $sExt = ".gif";
            } elseif ($file_type == "image/jpeg" || $file_type == "image/pjpeg") {
                $sExt = ".jpg";
            } elseif ($file_type == "image/png" || $file_type == "image/x-png") {
                $sExt = ".png";
            }
            if (!in_array($sExt, array('.gif', '.jpg', '.png'))) {
                $errors[] = "Image types alowed are (.gif, .jpg, .png) only!";
            }
            if ($file_size > 2097152000) {
                $errors[] = 'File size must be less than 2 MB';
            }
            $desired_dir = "$_SERVER[DOCUMENT_ROOT]/upload/file/";

            if (empty($errors)) {
                if (is_dir($desired_dir) == false) {
                    mkdir("$desired_dir", 0700);
                }
                if
                (move_uploaded_file($file_tmp, "$desired_dir/" . $file_name . $sExt)) {
                    $uploadedFiles[$key] = array($file_name . $sExt, 1);
                } else {
                    echo "Couldn't upload file " . $_FILES['files']['tmp_name'][$key];
                    $uploadedFiles[$key] = array($_FILES['files']['tmp_name'][$key], 0);
                }
            } else {

            }
        }
        foreach ($uploadedFiles as $key => $row) {
            if (!empty($row[1])) {
                $codestr = '$file' . ($key + 1) . ' = $row[0];';
                eval($codestr);
            } else {
                $codestr = '$file' . ($key + 1) . ' = NULL;';
                eval($codestr);
            }
        }
    }
    $orig_directory = "$desired_dir";
    $thumb_directory = "$_SERVER[DOCUMENT_ROOT]/upload/thumb/";
    $dir_handle = opendir($orig_directory);
    if ($dir_handle > 1) {
        $allowed_types = array('jpg', 'jpeg', 'gif', 'png');
        $file_type = array();
        $ext = '';
        $title = '';
        $i = 0;
        while ($file_name = readdir($dir_handle)) {
            if ($file_name == '.' || $file_name == '..') {
                continue;
            }
            $file_type = \explode('.', $file_name);
            $ext = strtolower(array_pop($file_type));
            $title1 = implode('.', $file_type);
            $title = htmlspecialchars($title1);
            if (in_array($ext, $allowed_types)) {
                $nw = 125;
                $nh = 90;
                $source = "$desired_dir{$file_name}";
                $stype1 = explode(".", $source);
                $stype = $stype1[count($stype1) - 1];
                $dest = "$_SERVER[DOCUMENT_ROOT]/upload/thumb/{$file_name}";
                $size = getimagesize($source);
                $w = $size[0];
                $h = $size[1];
                switch ($stype) {
                    case 'gif':
                        $simg = imagecreatefromgif($source);
                        break;
                    case 'jpg':
                        $simg = imagecreatefromjpeg($source);
                        break;
                    case 'png':
                        $simg = imagecreatefrompng($source);
                        break;
                }
                $dimg = resizePreservingAspectRatio($simg, $nw, $nh);
                imagepng($dimg, $dest);
                compress($source, "$desired_dir/" . $file_name, 50);
            }
        }closedir($dir_handle);
    }
    $stmt = $conn->prepare("INSERT INTO allpostdata(im1, im2, im3, im4)"
            . " VALUES (:im1, :im2, :im3, :im4)");

    $stmt->bindParam(':im1', $file1, PDO::PARAM_STR, 100);
    $stmt->bindParam(':im2', $file2, PDO::PARAM_STR, 100);
    $stmt->bindParam(':im3', $file3, PDO::PARAM_STR, 100);
    $stmt->bindParam(':im4', $file4, PDO::PARAM_STR, 100);
    if ($stmt->execute()) {
        header('Location: /post/price_plan.php');
    }exit;
}

function compress($source, $destination, $quality) {
    $info = getimagesize($source);
    if ($info['mime'] == 'image/jpeg') {
        $image = imagecreatefromjpeg($source);
    } elseif ($info['mime'] == 'image/gif') {
        $image = imagecreatefromgif($source);
    } elseif ($info['mime'] == 'image/png') {
        $image = imagecreatefrompng($source);
    }
    imagejpeg($image, $destination, $quality);
    return $destination;
}

function resizePreservingAspectRatio($img, $targetWidth, $targetHeight) {
    $srcWidth = imagesx($img);
    $srcHeight = imagesy($img);
    $srcRatio = $srcWidth / $srcHeight;
    $targetRatio = $targetWidth / $targetHeight;
    if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight)) {
        $imgTargetWidth = $srcWidth;
        $imgTargetHeight = $srcHeight;
    } else if ($targetRatio > $srcRatio) {
        $imgTargetWidth = (int) ($targetHeight * $srcRatio);
        $imgTargetHeight = $targetHeight;
    } else {
        $imgTargetWidth = $targetWidth;
        $imgTargetHeight = (int) ($targetWidth / $srcRatio);
    }
    $targetImg = imagecreatetruecolor($targetWidth, $targetHeight);
    $targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
    imagefill($targetImg, 0, 0, $targetTransparent);
    imagecolortransparent($targetImg, $targetTransparent);
    imagecopyresampled($targetImg, $img, 0, 0, 0, 0, $targetWidth, $targetHeight, $srcWidth, $srcHeight);
    return $targetImg;
}

Bounty Edit

if there is any good and faster function to do please.

all i need is to upload, rename, compress, create thumbnail and save name to DB

8
  • copy of thumb images for previously uploaded images also(create thumbnail for uploaded and uploading images too) do you mean if you upload multiple file, last image override previously created thumbnail ? Commented Dec 2, 2019 at 13:22
  • If I understand correctly, the script is not only handling the submitted images, but also re-processing previously uploaded images, already saved in the directory, and you want to prevent this. Right? Commented Dec 2, 2019 at 13:23
  • @jagad89 yes it overrides file ever time a form is submitted. Commented Dec 2, 2019 at 13:25
  • 3
    @sanojlawrence I suggest you spend some time diving into that. It has a lot of tools and existing frameworks to make tasks like this easy with minimal code Commented Dec 2, 2019 at 13:45
  • 1
    You should match the submitted images ($_FILES) in your while. Because you are processing every image in $thumb_directory at the moment. I agree with @Tschallacka your code could be more readable and maintainable with some refactoring. Commented Dec 2, 2019 at 14:38

3 Answers 3

1
+100

The code is need much more optimization. you are iterating the file folder again every time instead of looping the just uploaded files.

$desired_dir = "$_SERVER[DOCUMENT_ROOT]/upload/file/";
$thumb_directory = "$_SERVER[DOCUMENT_ROOT]/upload/thumb/";
$file = [];
$nw = 125;
$nh = 90;
if (!empty($_POST)) {
    if (isset($_FILES['files'])) {
        $uploadedFiles = array();
        foreach ($_FILES['files']['tmp_name'] as $key => $tmp_name) {
            $errors = array();
            $file_name = md5(uniqid("") . time());
            $file_size = $_FILES['files']['size'][$key];
            $file_tmp = $_FILES['files']['tmp_name'][$key];
            $file_type = $_FILES['files']['type'][$key];
            if ($file_type == "image/gif") {
                $sExt = ".gif";
            } elseif ($file_type == "image/jpeg" || $file_type == "image/pjpeg") {
                $sExt = ".jpg";
            } elseif ($file_type == "image/png" || $file_type == "image/x-png") {
                $sExt = ".png";
            }
            if (!in_array($sExt, array('.gif', '.jpg', '.png'))) {
                $errors[] = "Image types alowed are (.gif, .jpg, .png) only!";
            }
            if ($file_size > 2097152000) {
                $errors[] = 'File size must be less than 2 MB';
            }


            if (empty($errors)) {
                if (is_dir($desired_dir) == false) {
                    mkdir("$desired_dir", 0700);
                }
                $file_name_with_ext = $file_name . $sExt;
                $source = = $desired_dir . $file_name_with_ext ;
                if(!move_uploaded_file($file_tmp, $source)) {
                    echo "Couldn't upload file " . $_FILES['files']['tmp_name'][$key];
                    $file[] = NULL;
                }else{
                    $size = getimagesize($source);
                    $w = $size[0];
                    $h = $size[1];
                    switch ($sExt) {
                        case '.gif':
                            $simg = imagecreatefromgif($source);
                            break;
                        case '.jpg':
                            $simg = imagecreatefromjpeg($source);
                            break;
                        case '.png':
                            $simg = imagecreatefrompng($source);
                            break;
                    }
                    $dest = $thumb_directory. $file_name_with_ext ;
                    $dimg = resizePreservingAspectRatio($simg, $nw, $nh);
                    imagepng($dimg, $dest);
      // imagewebp($dimg, $dest);
                    compress($source, "$desired_dir"  . $file_name_with_ext , 50);
                    compress($dest, $dest , 50);
                    $file[] =   $file_name_with_ext ;
                }
            }else{
                // TODO: error handling
            } 
        }

    }

    $stmt = $conn->prepare("INSERT INTO allpostdata(im1, im2, im3, im4)"
            . " VALUES (:im1, :im2, :im3, :im4)");

    $stmt->bindParam(':im1', $file[0], PDO::PARAM_STR, 100);
    $stmt->bindParam(':im2', $file[1], PDO::PARAM_STR, 100);
    $stmt->bindParam(':im3', $file[2], PDO::PARAM_STR, 100);
    $stmt->bindParam(':im4', $file[3], PDO::PARAM_STR, 100);
    if ($stmt->execute()) {
        header('Location: https://google.com');
    }exit;
}

function compress($source, $destination, $quality) {
    $info = getimagesize($source);
    if ($info['mime'] == 'image/jpeg') {
        $image = imagecreatefromjpeg($source);
    } elseif ($info['mime'] == 'image/gif') {
        $image = imagecreatefromgif($source);
    } elseif ($info['mime'] == 'image/png') {
        $image = imagecreatefrompng($source);
    }
    imagejpeg($image, $destination, $quality);
    return $destination;
}

function resizePreservingAspectRatio($img, $targetWidth, $targetHeight) {
    $srcWidth = imagesx($img);
    $srcHeight = imagesy($img);
    $srcRatio = $srcWidth / $srcHeight;
    $targetRatio = $targetWidth / $targetHeight;
    if (($srcWidth <= $targetWidth) && ($srcHeight <= $targetHeight)) {
        $imgTargetWidth = $srcWidth;
        $imgTargetHeight = $srcHeight;
    } else if ($targetRatio > $srcRatio) {
        $imgTargetWidth = (int) ($targetHeight * $srcRatio);
        $imgTargetHeight = $targetHeight;
    } else {
        $imgTargetWidth = $targetWidth;
        $imgTargetHeight = (int) ($targetWidth / $srcRatio);
    }
    $targetImg = imagecreatetruecolor($targetWidth, $targetHeight);
    $targetTransparent = imagecolorallocate($targetImg, 255, 0, 255);
    imagefill($targetImg, 0, 0, $targetTransparent);
    imagecolortransparent($targetImg, $targetTransparent);
    imagecopyresampled($targetImg, $img, 0, 0, 0, 0, $targetWidth, $targetHeight, $srcWidth, $srcHeight);
    return $targetImg;
}
?>
Sign up to request clarification or add additional context in comments.

11 Comments

it saves only file name `it doesn't save file extension. I want to save file name with extension also.
sitll only file name is saved, i think this $file[] = $file_name; should be like this $file[] = $file_name.$sExt; so that file name and extension will be saved.
@sanojlawrence it saves data as per your expectation and process only uploaded files. Correct?
yes it does but, buti want file name should be save with extension! to DB. (.jpg or .png
hey a small issue after compression i have image size of 32kb (521*768) but the thumb file is 71kb (250*180) ! any solution ?
|
1

As part of your question you asked if there was "any good and faster function to do please."

https://github.com/delboy1978uk/image

Try this! (install via Composer or just require each of the classes in if you just drop the code in yourself)

<?php

use Del\Image;

$image = new Image('/path/to/your.jpg'); //or gif , etc

// Or...
$image = new Image();
$image->load('/path/to/my.png');

You'll then have all of these commands at your disposal:

$image->crop($width, $height, 'center'); // Crops the image, also accepts left or right as 3rd arg
$image->destroy(); // remove loaded image in the class. Frees up any memory
$image->getHeader(); // returns image/jpeg or equivalent
$image->getHeight(); // returns height in pixels
$image->getWidth(); // returns width in pixels
$image->output(); // output to browser
$image->output(true); // passing true returns raw image data string
$image->resize($width, $height); // resize to the given dimensions
$image->resizeAndCrop($width, $height); // resize to the given dimensions, cropping top/bottom or sides
$image->save(); // Save the image
$image->save('/path/to/save.jpg', $permissions, $compression); // Save as a different image
$image->scale(50); // Scale image to a percentage

Loop through your POSTed uploads, load them up, save the original, resize the image, and save the thumbnail. Existing images shouldn't be touched.

1 Comment

but am unable to find rename and compress methods. Will follow for more updates.
1

There are plenty bad php-programming-habits in that code (e.g. use of eval and general data-flow). To break it down: The script first validates the uploaded files and moves them to a temp directory. Then it calculates thumbnails for all files in the temp directory.

To change that we use an array which contains the filenames of uploading images.

// ...
$file_type = array();
$ext = '';
$title = '';
$i = 0;

// First change:
$validFileNames = array_column($uploadedFiles, 0);

while ($file_name = readdir($dir_handle)) {
  if ($file_name == '.' || $file_name == '..' || !in_array($file_name, $validFileNames)) {
    continue;
  }

  // Nothing changed beyond this point
  $file_type = \explode('.', $file_name);
  $ext = strtolower(array_pop($file_type));
  $title1 = implode('.', $file_type);
  $title = htmlspecialchars($title1);

  // ...
}

array_column($uploadedFiles, 0) reads the index 0 of every entry in $uploadedFiles, which contains the filename. So $validFileNames contains only filenames of uploading images.

We then check for every file in the temp-directory if its name is included in $uploadedFiles. If not then it was not uploading and can be ignored.

As for the request of a more general optimization:

<?php

$desired_dir = $_SERVER['DOCUMENT_ROOT'].'/upload/file/';

if (!empty($_POST)) {
    if (isset($_FILES['files'])) {
        $uploadedFiles = array();
        foreach ($_FILES['files']['tmp_name'] as $key => $uploadedFileName) {
            $errors = array();

            $destFilename = md5(uniqid('uploads', true).time());
            $uploadedSize = $_FILES['files']['size'][$key];
            $uploadedTmpName = $uploadedFileName;
            $uploadedType = $_FILES['files']['type'][$key];

            $sExt = null;
            if ($uploadedType == 'image/gif') {
                $sExt = '.gif';
            } elseif ($uploadedType == 'image/jpeg' || $uploadedType == 'image/pjpeg') {
                $sExt = '.jpg';
            } elseif ($uploadedType == 'image/png' || $uploadedType == 'image/x-png') {
                $sExt = '.png';
            }

            if (!in_array($sExt, array('.gif', '.jpg', '.png'))) {
                $errors[] = 'Image types alowed are (.gif, .jpg, .png) only!';
            }

            if ($uploadedSize > 2097152000) {
                $errors[] = 'File size must be less than 2 MB';
            }


            if (!empty($errors)) {
                // Todo: Error handling of $errors
                continue;
            }

            if (is_dir($desired_dir) == false) {
                mkdir($desired_dir, 0700);
            }

            $destFilePath = "$desired_dir/".$destFilename.$sExt;
            if (!move_uploaded_file($uploadedTmpName, $destFilePath)) {
                echo "Couldn't upload file ".$uploadedTmpName;
            }

            $nw = 125;
            $nh = 90;
            $source = $destFilePath;
            $stype1 = explode('.', $source);
            $stype = $stype1[count($stype1) - 1];
            $dest = $_SERVER['DOCUMENT_ROOT'].'/upload/thumb/'.$destFilename.$sExt;

            $size = getimagesize($source);
            $w = $size[0];
            $h = $size[1];
            switch ($stype) {
                case 'gif':
                    $simg = imagecreatefromgif($source);
                    break;
                case 'jpg':
                    $simg = imagecreatefromjpeg($source);
                    break;
                case 'png':
                    $simg = imagecreatefrompng($source);
                    break;
            }
            $dimg = resizePreservingAspectRatio($simg, $nw, $nh);
            imagepng($dimg, $dest);
            compress($source, "$desired_dir/".$file_name, 50);


            $uploadedFiles[] = $destFilePath;
        }

        $stmt = $conn->prepare('INSERT INTO allpostdata(im1, im2, im3, im4)'
            .' VALUES (?, ?, ?, ?)');

        if ($stmt->execute($uploadedFiles)) {
            header('Location: /post/price_plan.php');
        }
    }
    exit;
}

9 Comments

how do i solve bad php-programming-habits (e.g. use of eval and general data-flow) any solution
You could just do everything in the first foreach. The second foreach also as the while is unecessary. The use of eval() to generate the names of $file1 to $file4 is also not necessary since you could just execute the prepared statement multiple times.
Can you do it, As of now it creates thumbnail for only uploading images. can you please post a solution for bad php-programming-habits (e.g. use of eval and general data-flow)
Edited answer contains a refactoring of your script (functions not included)
i get error showing Undefined index: size tmp_name type, sExt also i want to get file name like $stmt->bindParam(':im1', $file[0], PDO::PARAM_STR, 100);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.