简体   繁体   English

在图像调整大小脚本(GD)期间释放内存

[英]Freeing up memory during an image resize script (GD)

I have the following code that takes $_POST ed images from a HTML <form> and uploads them. 我有以下代码,它们从HTML <form>中获取$_POST ed图像并上载它们。 It then re-sizes them all (up to twice) and saves these smaller images to the same directory. 然后,将它们全部重新调整大小(最多两次),并将这些较小的图像保存到同一目录中。

However, I am running out of memory when dealing with larger files. 但是,处理较大的文件时内存不足。

My question is not "how do I prevent X error from occuring?", but "How do I free up memory this script is using so it can continue?" 我的问题不是“如何防止X错误发生?”,而是“如何释放此脚本正在使用的内存以便它可以继续?”

<?php
if (!isset($_POST['SiteID']) || !filter_var($_POST['SiteID'], FILTER_VALIDATE_INT)) {
    header("Location: ./");
    exit();
}
$SiteID = $_POST['SiteID'];

if (!isset($_POST['GalleryID']) || !filter_var($_POST['GalleryID'], FILTER_VALIDATE_INT)) {
    header("Location: ./?SiteID=" . $SiteID . "&error=upload");
    exit();
}
$GalleryID = $_POST['GalleryID'];

$ImageFile = $_FILES['ImageFile'];

$Extensions = array("jpg", "jpeg");
$Timestamp = date("U");

require_once("db.php");

for ($X = 0; $X < count($_FILES['ImageFile']['name']); $X++) {
    $Extension = strtolower(pathinfo($ImageFile['name'][$X], PATHINFO_EXTENSION));
    if (in_array($Extension, $Extensions)) {
        if ($ImageFile['error'][$X] === UPLOAD_ERR_OK) {
            if ($ImageFile['size'][$X] <= 5 * 1024 * 1024) {
                $Filename = $GalleryID . "-" . $Timestamp . "-" . $X . "." . $Extension;
                move_uploaded_file($ImageFile['tmp_name'][$X], "uploads/" . $Filename);
                mysql_query("INSERT INTO NewGalleryImages SET GalleryID = $GalleryID, ImageFile = '$Filename', ImageCaption = ''");
                $Dimensions = getimagesize("uploads/" . $Filename);
                $Width = ($Dimensions[0] > 768 ? 768 : $Dimensions[0]);
                $Height = ($Dimensions[1] / $Dimensions[0]) * $Width;
                $Expl = explode(".", $Filename);
                $LargeFilename = $Expl[0] . "_gallery." . $Expl[1];
                $Source = "uploads/" . $Filename;
                $Canvas = imagecreatetruecolor($Width, $Height);
                $LargeImage = imagecreatefromjpeg($Source);
                imagecopyresampled($Canvas, $LargeImage, 0, 0, 0, 0, $Width, $Height, $Dimensions[0], $Dimensions[1]);
                imagejpeg($Canvas, "uploads/" . $LargeFilename, 100);
                imagedestroy($Canvas);
                $Width = 200;
                $Height = ($Dimensions[1] / $Dimensions[0]) * $Width;
                $Expl = explode(".", $Filename);
                $ThumbFilename = $Expl[0] . "_thumb." . $Expl[1];
                $Source = "uploads/" . $Filename;
                $Canvas = imagecreatetruecolor($Width, $Height);
                $ThumbImage = imagecreatefromjpeg($Source);
                imagecopyresampled($Canvas, $ThumbImage, 0, 0, 0, 0, $Width, $Height, $Dimensions[0], $Dimensions[1]);
                imagejpeg($Canvas, "uploads/" . $ThumbFilename, 100);
                imagedestroy($Canvas);
            } else {
                mysql_close();
                header("Location: ./?SiteID=" . $SiteID . "&error=size");
                exit();
            }
        } else {
            mysql_close();
            header("Location: ./?SiteID=" . $SiteID . "&error=unknown");
            exit();
        }
    } else {
        mysql_close();
        header("Location: ./?SiteID=" . $SiteID . "&error=type");
        exit();
    }
}

mysql_close();
header("Location: ./?SiteID=" . $SiteID . "&uploaded");
exit();

// var_dump($_POST);
// var_dump($_FILES);
// var_dump($ImageFile);
?>

I read about imagedestroy() in the PHP documentation, and have tried adding that in to my script in a couple of places, but 1) I'm not sure I'm destroying the right resource, and 2) I'm not sure it's actually clearing the memory. 我在PHP文档中阅读了有关imagedestroy()的信息,并尝试在几个地方将其添加到脚本中,但是1)我不确定自己是否销毁了正确的资源,以及2)我不确定它实际上是在清除内存。

I currently have the following setting on the server: 我目前在服务器上具有以下设置:

post_max_size = 64M
upload_max_filesize = 10M
max_input_time = 60
max_input_nesting_level = 64
max_execution_time = 120
memory_limit = 512M
max_input_vars = 1000

And this is the error message I am receiving: 这是我收到的错误消息:

Fatal error: Allowed memory size of 536870912 bytes exhausted
(tried to allocate 29440 bytes) in
/var/www/vhosts/example.com/httpsdocs/gallery-upload.php
on line 36

What I find odd is, no matter how much I increate the memory_limit to, the "extra" it needs to allocate is always the same: 29440 bytes . 我发现奇怪的是,无论我为memory_limit多少,它需要分配的“额外”始终是相同的: 29440 bytes

If I upload images individually, the script runs okay, but uploading more than two at a time throws the error. 如果我分别上传图像,脚本可以正常运行,但是一次上传两个以上会引发错误。 More than 512MB of memory to resize two images seems excessive, no? 调整两个图像大小所需的超过512MB的内存似乎过多,不是吗? Or is it still not enough memory? 还是内存不足? I'm not sure how much this server can spare...! 我不确定该服务器可以节省多少...! How can I reduce my total memory usage? 如何减少总内存使用量?

After a little bit of playing about, I've managed to get my script to work. 玩了一点之后,我设法使脚本工作了。 What I needed to do was use imagedestroy() on both the new image, and the original image after each resize, ie: 我需要做的是在每次调整大小后在新图像原始图像上都使用imagedestroy() ,即:

imagedestroy($LargeImage);
imagedestroy($Canvas);

I'm not sure if this is everything that could be done to free up memory, but it's working (for now). 我不确定这是否是释放内存所能做的所有事情,但是(目前)它正在工作。 I'm sure someone will test my memory limits again with an even larger image file soon... 我敢肯定有人很快会用更大的图像文件再次测试我的内存限制...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM