2011-06-10 42 views
2

我目前正在爲Prestashop構建一個導入模塊。該模塊正在導入約3000種產品,並需要將每個產品圖像調整爲5種不同的縮略圖格式。問題是:腳本消耗了大量內存。在這個過程中,我正在談論100 MB峯值和高達27 MB。我有點羞愧地說我對整個內存管理的東西不是很熟悉,所以任何幫助都是值得歡迎的!調整圖像大小並耗盡內存

我使用的代碼如下。 resizeImg方法應該是最有趣的,其他方法僅用於說明我如何處理任務。有誰知道我爲什麼會獲得超過100MB的內存峯值?

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); 
} 
+0

你有沒有找到解決這個問題的辦法?我在Prestashop模塊中遇到了同樣的問題 – Matt 2016-09-02 17:17:49

+0

我不記得我們是如何解決這個問題的。我們很可能採取了不同的方法。 – Martijn 2016-09-03 18:30:13

回答

1

這些圖像有多大?請記住,一旦它們加載到GD中,它們將被解壓縮爲每像素3(或4)字節。 24位的100MB就足夠用於6666x5000左右的圖像。你有沒有檢查調整大小計算工作正常?如果他們錯了,你可能會試圖錯誤地創建一個巨大的'dest'圖像。

我沒有看到你在哪裏寫出調整大小的圖像。有很多調整大小/複製,但你沒有imagejpeg()imagepng()等......寫出調整大小的圖像。

+0

Hi Marc。所有圖像都具有500x500像素的確切大小。如我錯了請糾正我。我想這意味着一個圖像是250.000像素。在GD解壓縮後,250.000 * 4 = 1 mnn個字節,大約爲1MB。但是我不斷地在循環中清理這些資源,爲什麼我會得到100MB的峯值? P.s:修改了imagejpeg-method的代碼! – Martijn 2011-06-10 16:01:59

+0

很難說。我無法發現任何資源泄漏。嘗試在各種調用之前/之後噴灑一些'echo memory_get_usage(true)'調用以查看用法向上射擊的位置。 – 2011-06-10 16:10:13

+0

使用不是特別在任何地方向上拍攝。我注意到,在下載和調整一些圖像的大小後,256或512 KB的另一個內存塊會被保留,但僅此而已。問題是:執行該代碼大約10.000次後,那些265 KB的塊將使用的內存增加到異常高度。 – Martijn 2011-06-11 11:30:20