К сожалению, вы будете ограничены лимитом памяти. Библиотека GD выглядит так, как будто у нее ужасное управление памятью. Я только что попытался загрузить изображение с размерами 3951x2520, и использование памяти сценариев возросло с 512 КБ до загрузки до примерно 50 МБ после загрузки (PHP 5.3.3, Windows 7 Home x64). Фактическое изображение должно занимать только около 28,49 МБ памяти, так почему же GD почти вдвое увеличивает это количество? Понятия не имею.
Редактировать : На самом деле, похоже, причина в том, что GD хранит изображение во внутреннем формате GD2, который неэффективно использует память.
Edit2 : Похоже, формат GD2 на самом деле раздут только на 67% по сравнению с настоящим растровым растровым изображением. Удивительно, что оригинальный формат GD занимает меньше места, чем само оригинальное изображение или GD2. Я полагаю, что это связано с размыванием, которое заметно на выходе. Единственный способ получить файл, загруженный в исходный формат GD, - это сначала загрузить его, используя функцию изображения (например, imagecreatefromjpeg), а затем сохранить его, используя imagegd
(не imagegd2
), а затем снова загрузить его с * 1011. *. Это не очень эффективно, и сглаживание определенно происходит.
Окончательное редактирование :
Мне кажется, это лучшая функция, чем та, что была у меня ниже. Вы даете ему имя файла вашего файла вместе с целевой высотой и шириной, и он проверит доступную память и вернет истину или ложь, если у вас достаточно для изменения размера. Если вы предпочитаете просто знать приблизительно, сколько памяти требуется, вы можете передать true в качестве параметра $ returnRequiredMem.
function checkMemAvailbleForResize($filename, $targetX, $targetY,$returnRequiredMem = false, $gdBloat = 1.68) {
$maxMem = ((int) ini_get('memory_limit') * 1024) * 1024;
$imageSizeInfo = getimagesize($filename);
$srcGDBytes = ceil((($imageSizeInfo[0] * $imageSizeInfo[1]) * 3) * $gdBloat);
$targetGDBytes = ceil((($targetX * $targetY) * 3) * $gdBloat);
$totalMemRequired = $srcGDBytes + $targetGDBytes + memory_get_usage();
if ($returnRequiredMem) return $srcGDBytes + $targetGDBytes;
if ($totalMemRequired > $maxMem) return false;
return true;
}
Примеры: * 1 021 *
if (!checkMemAvailableForResize('path/to/file.jpg', 640,480)) die('Cannot resize!');
или
$totalBytesNeeded = checkMemAvailableForResize('path/to/file.jpg',640,480,true);
Кроме того, вы можете настроить параметр $ gdBloat в случае, если 68% слишком мало или слишком много накладных расходов:
checkMemAvailableForResize('path/to/file.jpg',640,480,false, 1.69);