【问题标题】:PHP GD resize/crop image before uploading上传前 PHP GD 调整大小/裁剪图像
【发布时间】:2015-02-22 04:48:18
【问题描述】:

我一直在尝试从 HTML 表单中获取文件,然后创建一个新文件并使用“imagecopyresampled”从中获取中心方块,适合 X 或 Y,具体取决于哪个更小。

不幸的是,我对处理这么多图像和临时名称感到有些困惑,并且在将文件复制到系统上的用户文件时遇到了麻烦。 代码如下:

if($_FILES){
    $valid = validate_image("avatar");

    if ($valid){
        list($width, $height, $type) = getimagesize($_FILES['avatar']['tmp_name']);

        $scale = $width/$height;
        $pixels = 150;
        $tmp_name = $_FILES['avatar']['tmp_name'];

        switch ($type) {
            case IMAGETYPE_GIF:
                $source = imagecreatefromgif($tmp_name);
                break;

            case IMAGETYPE_JPEG:
            case IMAGETYPE_JPG:
                $source = imagecreatefromjpeg($tmp_name);
                break;

            case IMAGETYPE_PNG:
                $source = imagecreatefrompng($tmp_name);
                break;
        }

        $upload = imagecreatetruecolor($pixels, $pixels);

        //sketchy image math: Get whichever coordinate is smaller and that will be 150 on the thumbnail from top to bottom (or left to right).
        //Then for the other one you know the size will be 150, but only for the part starting at (Coordinate/2)-SMALLERCOORD/2 to (coord/2)+SMALLERCOORD/2

        if ($width>$height){
            imagecopyresampled ($upload, $source, 0, 0, 0, ($width-$height/2), 150, 150, $height, $height);
        } else if ($width<=$height){
            imagecopyresampled ($upload, $source, 0, 0, 0, ($height-$width/2), 150, 150, $width, $width);
        }

        $name = "./users/$id/avatar.png";

        imagepng($upload, $tmp_name);

        if (!(move_uploaded_file($tmp_name, $name))) $fail .= "<h3>ERROR UPLOADING AVATAR. TRY AGAIN LATER OR CONTACT US.</h3><br>";
    }
}

首先让我看看我是否理解代码是如何正常工作的: 我得到文件,检查它是否对我的功能有效。然后我得到它的大小和类型。我检查类型并从中在服务器内存上创建一个图像,并在我想要的大小上创建另一个空图像。然后我实际上将调整大小和裁剪的图像复制到我创建的上传图像上。 如果我愿意,我可以使用 imagedestroy 删除临时“源”图像,对吗? 接下来,我尝试从服务器内存中的“上传”图像制作一个 png 文件。 这是我认为我弄错的地方,我无法覆盖临时文件,可以吗? 然后我尝试将图像临时图像放在应该上传的位置,但这不起作用。

我做对了吗?如何修复此代码? 感谢您的关注。

【问题讨论】:

    标签: php image upload resize php-gd


    【解决方案1】:

    在网上查了很多资料后,我发现最大的问题在于运行 apache 的用户(www-data)。

    所以我进入 /etc/apache2/envvars 并将 APACHE_RUN_USER 更改为文件夹的所有者。 然后我必须在 /etc/lib/php5 上做一个 chown 以便会话能够坚持/与新用户一起工作。

    有了这个,我现在能够访问该文件夹,以便服务器能够在其上写入和修改。 然后我在代码中添加了这部分:

    $dir = "./users/$id/";
    $oldumask = mask(0); 
    mkdir ("$dir");
    chmod("$dir", 0750);
    umask($oldumask);
    

    这是在创建 png 图像之前添加的。 然后我删除了“move_uploaded_file”代码,只使用了 Jacob Budin 建议的 imagepng 函数:

    if(!imagepng($upload, $name)) $fail .= "<h3>ERROR!<h3><br>";
    

    这解决了所有问题(但裁剪代码错误的事实,但这不相关)。 我仍然不能 100% 确定 GD/PHP 如何很好地处理图像,但这很有效。

    【讨论】:

      【解决方案2】:

      关于您的缩略图生成的逻辑不正确,但您更紧迫的问题是保存图像文件。您正在尝试保存在文件系统的根目录 (/users/$id/avatar.png),可能没有这样做所需的权限。

      虽然您可以保存回上传路径,但这不是必需的。在imagepng 中,只需将文件保存到您的目的地(例如/var/web/app/public/uploads/$id/avatar.png)。您还可以使用魔术常量__DIR__ 指定相对于执行执行的 PHP 文件的路径。

      就裁剪而言,考虑使用预构建的函数或库来生成缩略图。我可以在这里复制一些代码,但其他人已经多次将这个问题打死(并纠正了其他潜在问题,如透明度)。您可以查看 imagecopyresampled 上的文档(和用户 cmets),或使用复杂的库,例如 Imagine

      【讨论】:

      • 我的错误。它不是“/users/$id/avatar.png”。我在编辑代码时删除了太多,它应该是相对于PHP文件的路径。 “./users/$id/avatar.png”。因此,用户文件夹位于 PHP 代码所在的同一目录中。
      猜你喜欢
      • 2010-11-03
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 2015-10-27
      • 2014-02-10
      • 1970-01-01
      • 2011-09-23
      • 2011-11-11
      相关资源
      最近更新 更多