在图像调整脚本 (GD) 期间释放内存
Freeing up memory during an image resize script (GD)
我有以下代码,它从 HTML <form>
中获取 $_POST
ed 图像并上传它们。然后重新调整它们的大小(最多两次)并将这些较小的图像保存到同一目录。
但是,我在处理较大的文件时 运行 内存不足。
我的问题不是"how do I prevent X error from occuring?",而是"How do I free up memory this script is using so it can continue?"
<?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);
?>
我在 PHP 文档中阅读了有关 imagedestroy()
的内容,并尝试将其添加到我的脚本中的几个地方,但是 1) 我不确定我是否正在破坏正确的资源,以及 2) 我不确定它是否真的在清除内存。
我目前在服务器上有以下设置:
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
这是我收到的错误消息:
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
我觉得奇怪的是,无论我将 memory_limit
创建多少,它需要分配的 "extra" 总是相同的:29440 bytes
.
如果我单独上传图片,脚本运行正常,但一次上传两个以上会引发错误。调整两个图像的大小超过 512MB 的内存似乎过多,不是吗?或者还是内存不够?我不确定这台服务器能节省多少……! 如何减少总内存使用量?
经过一些尝试,我已经成功地让我的脚本开始工作了。我需要做的是在每次调整大小后对新图像 和 都使用 imagedestroy()
原始图像,即:
imagedestroy($LargeImage);
imagedestroy($Canvas);
我不确定这是否是释放内存的所有方法,但它正在工作(目前)。我相信很快就会有人用更大的图像文件再次测试我的内存限制...
我有以下代码,它从 HTML <form>
中获取 $_POST
ed 图像并上传它们。然后重新调整它们的大小(最多两次)并将这些较小的图像保存到同一目录。
但是,我在处理较大的文件时 运行 内存不足。
我的问题不是"how do I prevent X error from occuring?",而是"How do I free up memory this script is using so it can continue?"
<?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);
?>
我在 PHP 文档中阅读了有关 imagedestroy()
的内容,并尝试将其添加到我的脚本中的几个地方,但是 1) 我不确定我是否正在破坏正确的资源,以及 2) 我不确定它是否真的在清除内存。
我目前在服务器上有以下设置:
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
这是我收到的错误消息:
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
我觉得奇怪的是,无论我将 memory_limit
创建多少,它需要分配的 "extra" 总是相同的:29440 bytes
.
如果我单独上传图片,脚本运行正常,但一次上传两个以上会引发错误。调整两个图像的大小超过 512MB 的内存似乎过多,不是吗?或者还是内存不够?我不确定这台服务器能节省多少……! 如何减少总内存使用量?
经过一些尝试,我已经成功地让我的脚本开始工作了。我需要做的是在每次调整大小后对新图像 和 都使用 imagedestroy()
原始图像,即:
imagedestroy($LargeImage);
imagedestroy($Canvas);
我不确定这是否是释放内存的所有方法,但它正在工作(目前)。我相信很快就会有人用更大的图像文件再次测试我的内存限制...