PHP上传后调整图片大小

38

我有一个表单,用户需要插入一些数据并上传一张图片。

为处理这张图片,我使用了以下代码:

define("MAX_SIZE", "10000");
$errors = 0;
$image = $_FILES["fileField"]["name"];
$uploadedfile = $_FILES['fileField']['tmp_name'];
if($image){
    $filename = stripslashes($_FILES['fileField']['name']);
    $extension = strtolower(getExtension($filename));
    if (($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif")){
        echo ' Unknown Image extension ';
        $errors = 1;
    } else {
        $newname = "$product_cn.$extension";
        $size = filesize($_FILES['fileField']['tmp_name']);
        if ($size > MAX_SIZE*1024){
            echo "You have exceeded the size limit";
            $errors = 1;
        }
        if($extension == "jpg" || $extension == "jpeg" ){
            $uploadedfile = $_FILES['file']['tmp_name'];
            $src = imagecreatefromjpeg($uploadedfile);
        } else if($extension == "png"){
            $uploadedfile = $_FILES['file']['tmp_name'];
            $src = imagecreatefrompng($uploadedfile);
        } else {
            $src = imagecreatefromgif($uploadedfile);
        }
        list($width, $height) = getimagesize($uploadedfile);
        $newwidth = 60;
        $newheight = ($height/$width)*$newwidth;
        $tmp = imagecreatetruecolor($newwidth, $newheight);
        $newwidth1 = 25;
        $newheight1 = ($height/$width)*$newwidth1;
        $tmp1 = imagecreatetruecolor($newwidth1, $newheight1);
        imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
        imagecopyresampled($tmp1, $src, 0, 0, 0, 0, $newwidth1, $newheight1, $width, $height);
        $filename = "../products_images/$newname";
        $filename1 = "../products_images/thumbs/$newname";
        imagejpeg($tmp, $filename, 100); // file name also indicates the folder where to save it to
        imagejpeg($tmp1, $filename1, 100);
        imagedestroy($src);
        imagedestroy($tmp);
        imagedestroy($tmp1);
    }
}

getExtension函数:

function getExtension($str) {
    $i = strrpos($str, ".");
    if (!$i) { return ""; }
    $l = strlen($str) - $i;
    $ext = substr($str,$i+1,$l);
    return $ext;
}

因为我不太熟悉那些函数,所以在代码中写了一些注释。

但出现了问题,当我进入“product_images”或“product_images / thumbs”文件夹时,找不到任何已上传的图像。

你知道我的代码有什么问题吗?应该有一个60像素宽的图片和一个25像素宽的图片。

注意:像$product_cn这样声明位置不明确的变量已经在工作正常的代码块之前声明了(已测试)。如果需要,请随时要求查看该代码。

14个回答

52

这里有另一个简单易懂的解决方案:

$maxDim = 800;
$file_name = $_FILES['myFile']['tmp_name'];
list($width, $height, $type, $attr) = getimagesize( $file_name );
if ( $width > $maxDim || $height > $maxDim ) {
    $target_filename = $file_name;
    $ratio = $width/$height;
    if( $ratio > 1) {
        $new_width = $maxDim;
        $new_height = $maxDim/$ratio;
    } else {
        $new_width = $maxDim*$ratio;
        $new_height = $maxDim;
    }
    $src = imagecreatefromstring( file_get_contents( $file_name ) );
    $dst = imagecreatetruecolor( $new_width, $new_height );
    imagecopyresampled( $dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
    imagedestroy( $src );
    imagepng( $dst, $target_filename ); // adjust format as needed
    imagedestroy( $dst );
}

参考: PHP按比例调整图像大小,最大宽度或重量

编辑:清理了代码并简化了一些。感谢@jan-mirus的评论。


3
可以的,为了确保正确理解您的问题,您是在询问为什么需要两次提取图像尺寸吗? - Jan Mirus
7
太棒了!尽管它最后缺少一行非常重要的代码:move_uploaded_file($_FILES['myFile']['tmp_name'], $destinationFilePath); - HerrimanCoder
@jan-mirus 这是因为宽度和高度变量在中途被更改了。现在已经不那么混乱了,应该更容易阅读。 - zeusstl
有人能解释一下图片文件被发送到哪里了吗?我似乎找不到它?我想要将一个调整大小的图像插入到数据库中。我想象它是$target_filename,但我已经达到了我的知识极限。 - Neil White
我有一个问题,为什么照片的位置是横向的而不是竖向的?我的意思是我拍摄的是竖直的照片,但结果却是横向的。 - undefined

26

4
警告:该脚本受GPL保护,因此您需要购买商业版本(15美元)或在GPL下公开您的网站源代码。 - The Godfather

11

// 这是我用来自动调整每张插入的图片大小为100乘50像素,并将图像格式转换为jpeg的示例,希望这也能帮到你

if($result){
$maxDimW = 100;
$maxDimH = 50;
list($width, $height, $type, $attr) = getimagesize( $_FILES['photo']['tmp_name'] );
if ( $width > $maxDimW || $height > $maxDimH ) {
    $target_filename = $_FILES['photo']['tmp_name'];
    $fn = $_FILES['photo']['tmp_name'];
    $size = getimagesize( $fn );
    $ratio = $size[0]/$size[1]; // width/height
    if( $ratio > 1) {
        $width = $maxDimW;
        $height = $maxDimH/$ratio;
    } else {
        $width = $maxDimW*$ratio;
        $height = $maxDimH;
    }
    $src = imagecreatefromstring(file_get_contents($fn));
    $dst = imagecreatetruecolor( $width, $height );
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1] );

    imagejpeg($dst, $target_filename); // adjust format as needed


}

move_uploaded_file($_FILES['pdf']['tmp_name'],"pdf/".$_FILES['pdf']['name']);

2
尽管这段代码可能有助于解决问题,但它并没有解释为什么以及如何回答这个问题。提供这种额外的上下文将显著提高其长期教育价值。请编辑您的答案以添加说明,包括适用的限制和假设。 - Toby Speight
1
最佳答案 - 没有任何库需要!应该删除 move_uploaded_file,因为 imagejpeg 将文件移动到新目标 $target_filename。 - realmag777
为什么$target_filename和$fn是相同的?为什么不只使用一个? - Shawn T

4
<form action="<?php echo $_SERVER["PHP_SELF"];  ?>" method="post" enctype="multipart/form-data" id="something" class="uniForm">
    <input name="new_image" id="new_image" size="30" type="file" class="fileUpload" />
    <button name="submit" type="submit" class="submitButton">Upload Image</button>
</form>

<?php
    if(isset($_POST['submit'])){
      if (isset ($_FILES['new_image'])){              
          $imagename = $_FILES['new_image']['name'];
          $source = $_FILES['new_image']['tmp_name'];
          $target = "images/".$imagename;
          $type=$_FILES["new_image"]["type"];

          if($type=="image/jpeg" || $type=="image/jpg"){
          move_uploaded_file($source, $target);
          //orginal image making part

          $imagepath = $imagename;
          $save = "images/" . $imagepath; //This is the new file you saving
          $file = "images/" . $imagepath; //This is the original file
          list($width, $height) = getimagesize($file) ;
          $modwidth = 1000;
          $diff = $width / $modwidth;
          $modheight = $height / $diff;   
          $tn = imagecreatetruecolor($modwidth, $modheight) ;
          $image = imagecreatefromjpeg($file) ;
          imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
          echo "Large image: <img src='images/".$imagepath."'><br>";                     
          imagejpeg($tn, $save, 100) ;

          //thumbnail image making part
          $save = "images/thumb/" . $imagepath; //This is the new file you saving
          $file = "images/" . $imagepath; //This is the original file   
          list($width, $height) = getimagesize($file) ;
          $modwidth = 150;
          $diff = $width / $modwidth;
          $modheight = $height / $diff;
          $tn = imagecreatetruecolor($modwidth, $modheight) ;
          $image = imagecreatefromjpeg($file) ;
          imagecopyresampled($tn, $image, 0, 0, 0, 0, $modwidth, $modheight, $width, $height) ;
        //echo "Thumbnail: <img src='images/sml_".$imagepath."'>";
          imagejpeg($tn, $save, 100) ;
          }
        else{
            echo "File is not image";
            }
      }
    }
?>

1
不要回答已经有被接受的答案的年代久远的问题,尝试回答那些还没有答案的新问题。 - Anuraag Baishya
当我上传一个300X200大小的图像时,它会将其转换为1000宽度。它应该在图像大小大于$modwidth 1000时进行转换。我该怎么做? - Shiva
@AnuraagBaishya,你不应该这样说。他的回答帮助了我,节省了我很多时间。 - Vahid Naghash

3

在@zeusstl的答案基础上,针对上传多张图片的情况:

function img_resize()
{

  $input = 'input-upload-img1'; // Name of input

  $maxDim = 400;
  foreach ($_FILES[$input]['tmp_name'] as $file_name){
    list($width, $height, $type, $attr) = getimagesize( $file_name );
    if ( $width > $maxDim || $height > $maxDim ) {
        $target_filename = $file_name;
        $ratio = $width/$height;
        if( $ratio > 1) {
            $new_width = $maxDim;
            $new_height = $maxDim/$ratio;
        } else {
            $new_width = $maxDim*$ratio;
            $new_height = $maxDim;
        }
        $src = imagecreatefromstring( file_get_contents( $file_name ) );
        $dst = imagecreatetruecolor( $new_width, $new_height );
        imagecopyresampled( $dst, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
        imagedestroy( $src );
        imagepng( $dst, $target_filename ); // adjust format as needed
        imagedestroy( $dst );
    }
  }
}

2

如果你想直接使用 Imagick(大部分 PHP 发行版都包含它),很容易实现:

$image = new Imagick();
$image_filehandle = fopen('some/file.jpg', 'a+');
$image->readImageFile($image_filehandle);

$image->scaleImage(100,200,FALSE);

$image_icon_filehandle = fopen('some/file-icon.jpg', 'a+');
$image->writeImageFile($image_icon_filehandle);

您可能希望根据原始图像更动态地计算宽度和高度。您可以使用上面的示例,通过$image->getImageHeight();$image->getImageWidth();获取图像的当前宽度和高度。


1

这个东西对我有用。 没有使用任何外部库。

    define ("MAX_SIZE","3000");
 function getExtension($str) {
         $i = strrpos($str,".");
         if (!$i) { return ""; }
         $l = strlen($str) - $i;
         $ext = substr($str,$i+1,$l);
         return $ext;
 }

 $errors=0;

 if($_SERVER["REQUEST_METHOD"] == "POST")
 {
    $image =$_FILES["image-1"]["name"];
    $uploadedfile = $_FILES['image-1']['tmp_name'];


    if ($image) 
    {

        $filename = stripslashes($_FILES['image-1']['name']);

        $extension = getExtension($filename);
        $extension = strtolower($extension);


 if (($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif")) 
        {
            echo "Unknown Extension..!";
        }
        else
        {

 $size=filesize($_FILES['image-1']['tmp_name']);


if ($size > MAX_SIZE*1024)
{
    echo "File Size Excedeed..!!";
}


if($extension=="jpg" || $extension=="jpeg" )
{
$uploadedfile = $_FILES['image-1']['tmp_name'];
$src = imagecreatefromjpeg($uploadedfile);

}
else if($extension=="png")
{
$uploadedfile = $_FILES['image-1']['tmp_name'];
$src = imagecreatefrompng($uploadedfile);

}
else 
{
$src = imagecreatefromgif($uploadedfile);
echo $scr;
}

list($width,$height)=getimagesize($uploadedfile);


$newwidth=1000;
$newheight=($height/$width)*$newwidth;
$tmp=imagecreatetruecolor($newwidth,$newheight);


$newwidth1=1000;
$newheight1=($height/$width)*$newwidth1;
$tmp1=imagecreatetruecolor($newwidth1,$newheight1);

imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

imagecopyresampled($tmp1,$src,0,0,0,0,$newwidth1,$newheight1,$width,$height);


$filename = "../images/product-image/Cars/". $_FILES['image-1']['name'];

$filename1 = "../images/product-image/Cars/small". $_FILES['image-1']['name'];



imagejpeg($tmp,$filename,100);

imagejpeg($tmp1,$filename1,100);

imagedestroy($src);
imagedestroy($tmp);
imagedestroy($tmp1);
}}

}

0

这个类可以与任何框架或核心PHP一起使用。

要获取完整的详细信息,请访问下面的链接。

https://learncodeweb.com/web-development/laravel-9-upload-multiple-files-and-image-resizer/

在 Laravel 中,有许多库可用于上传和调整多个图像。我提供了一个简单易用的解决方案,它是基于 GD 的类。

您只需要使用以下命令通过 composer 进行安装即可。

composer require learncodeweb/filesupload

安装后,可以使用以下命令重新创建自动加载文件。 (可选)

composer dump-autoload

如何在Laravel 8/9中导入并使用(已测试)。

use anyFileUpload\FilesUploadAndImageResize as anyFilesUpload;
 
$files = new anyFilesUpload('array', ['jpg', 'jpeg', 'png'], public_path('uploads'), 0777);
$files->uploadFiles('files', 250, '', '', 100, '850', ['350']);
 
dd($files->uploadedData);

上传文件到服务器后,会返回所有已上传的文件名。您可以将这些文件名存储到您的数据库中。

提供的功能

  1. 上传单个或多个文件。
  2. 上传任何类型的文件(不仅限于图像)。
  3. 图片文件可以调整大小。
  4. 创建图像缩略图(保持图像纵横比)。
  5. 您可以添加水印(文本、图像)。
  6. 可轻松与表单集成。
  7. 在一次上传中创建任意数量的缩略图。
  8. 缩略图文件夹的路径可自定义设置。
  9. 可自定义设置缩略图的大小和尺寸。
  10. 文件扩展名过滤。
  11. 上传文件的文件大小限制。

0

基于zeusstl的解决方案,如果您希望宽度或高度使用maxDim,并且最高尺寸是基于此设置的,则可以将其添加到第四行:

if ($height > $width) {
    $maxDim = $maxDim * ($height/$width);
} else {
    $maxDim = $maxDim * ($width/$height);
}

0
你也可以使用Imagine库。它使用GD和Imagick。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接