Изменение размера изображения и нехватка памяти - PullRequest
2 голосов
/ 10 июня 2011

В настоящее время я создаю модуль импорта для 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 && $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 Ответ

1 голос
/ 10 июня 2011

Насколько велики эти изображения? Помните, что после загрузки в GD они распаковываются в 3 (или 4) байта на пиксель. 100 МБ на 24 бита достаточно для изображения 6666x5000 или около того. Вы проверили, что вычисления изменения размера работают правильно? Если они не правы, вы можете попытаться создать очень большое изображение dest по ошибке.

Я тоже не вижу, где вы пишете измененное изображение. Существует множество вариантов изменения размера / копирования, но нигде у вас нет imagejpeg() или imagepng() и т. Д. ... для записи измененного изображения.

...