#php #image #memory #resize #jpeg
#php #изображение #память #изменение размера #jpeg
Вопрос:
В настоящее время я создаю модуль импорта для Prestashop. Этот модуль импортирует около 3000 продуктов, и ему необходимо изменить размер каждого изображения продукта до 5 различных форматов миниатюр. Проблема в том, что скрипт потребляет МНОГО памяти. Я говорю о максимальных 100 МБ и до 27 МБ во время процесса. Мне немного стыдно признаться, что я не очень хорошо знаком со всеми вопросами управления памятью, так что любая помощь приветствуется!
Код, который я использую, следующий. Метод resizeImg должен быть самым интересным, другие методы приведены только для иллюстрации того, как я обрабатываю задачи. Кто-нибудь знает, почему я получаю пик памяти более 100 МБ?
public function main() {
foreach( $products as $product ) {
self::copyImg( $imageURL );
}
}
static private function copyImg( $imageURL ) {
// Copy image from $imageURL to temp folder
foreach( $imageTypes as $type ) {
self::resizeImg( $tempImage, $destination, $type['width'], $type['height']);
}
}
static private function resizeImg( $sourceFile, $destFile, $destWidth, $destHeight )
{
list( $sourceWidth, $sourceHeight, $type, $attr ) = getimagesize( $sourceFile );
if ( is_null( $destWidth ) ) $destWidth = $sourceWidth;
if ( is_null( $destHeight ) ) $destHeight = $sourceHeight;
$sourceImage = imagecreatefromjpeg( $sourceFile );
$widthDiff = $destWidth / $sourceWidth;
$heightDiff = $destHeight / $sourceHeight;
if ( $widthDiff > 1 amp;amp; $heightDiff > 1 ) {
$nextWidth = $sourceWidth;
$nextHeight = $sourceHeight;
} else {
if ( Configuration::get( 'PS_IMAGE_GENERATION_METHOD' ) == 2 || ( ! Configuration::get( 'PS_IMAGE_GENERATION_METHOD' ) AND $widthDiff > $heightDiff ) ) {
$nextHeight = $destHeight;
$nextWidth = round( $sourceWidth * $nextHeight / $sourceHeight );
$destWidth = ( ! Configuration::get( 'PS_IMAGE_GENERATION_METHOD' ) ? $destWidth : $nextWidth );
} else {
$nextWidth = $destWidth;
$nextHeight = round( $sourceHeight * $destWidth / $sourceWidth );
$destHeight = ( ! Configuration::get( 'PS_IMAGE_GENERATION_METHOD' ) ? $destHeight : $nextHeight );
}
}
$destImage = imagecreatetruecolor( $destWidth, $destHeight );
$white = imagecolorallocate( $destImage, 255, 255, 255 );
imagefilledrectangle( $destImage, 0, 0, $destWidth, $destHeight, $white );
imagecopyresampled( $destImage, $sourceImage, ( ( $destWidth - $nextWidth ) / 2 ), ( ( $destHeight - $nextHeight ) / 2 ), 0, 0, $nextWidth, $nextHeight, $sourceWidth, $sourceHeight );
imagecolortransparent( $destImage, $white );
imagejpeg( $destImage, $destFile, 90 );
imagedestroy( $sourceImage );
imagedestroy( $destImage );
}
Комментарии:
1. Вы когда-нибудь находили решение этой проблемы? Я борюсь с тем же самым в модуле Prestashop
2. Я не помню, как мы решили эту проблему. Скорее всего, мы использовали другой подход.
Ответ №1:
Насколько велики эти изображения? Помните, что как только они загружаются в GD, они распаковываются до 3 (или 4) байт на пиксель. 100 МБ при 24 битах достаточно для изображения размером 6666×5000 или около того. Вы проверили, что вычисления изменения размера работают правильно? Если они ошибочны, возможно, вы пытаетесь по ошибке создать слишком большое изображение «dest».
Я тоже не вижу, куда вы записываете изображение с измененным размером. Существует множество операций изменения размера / копирования, но нигде у вас нет imagejpeg()
или imagepng()
etc …, чтобы записать измененное изображение.
Комментарии:
1. Привет, Марк. Все изображения имеют точный размер 500x500px. Поправьте меня, если я ошибаюсь. Я предполагаю, что это означает, что одно изображение имеет размер 250 000 пикселей. После того, как GD распакует его, 250.000 * 4 = 1 миллион байт, что составляет примерно 1 МБ. Но я постоянно очищаю эти ресурсы в своем цикле, так почему же я получаю пик в 100 МБ? P.s: модифицировал свой код для imagejpeg-метода!
2. трудно сказать. Я не могу сразу обнаружить никаких утечек ресурсов. Попробуйте выполнить несколько
echo memory_get_usage(true)
вызовов до / после различных вызовов, чтобы увидеть, где использование резко возрастает.3. Использование не направлено вверх где-либо конкретно. Я замечаю, что после загрузки и изменения размера нескольких изображений резервируется еще один блок памяти объемом 256 или 512 КБ, но не более того. Проблема в том, что примерно после 10000-кратного выполнения этого фрагмента кода эти блоки по 265 КБ увеличат объем используемой памяти до ненормальных значений.