问题
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
回答1:
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;
}
?>
回答2:
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.
回答3:
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;
}
来源:https://stackoverflow.com/questions/59115161/error-while-creating-thumbnail-in-php-for-multiple-image-upload