解決PHP處理圖片時內存占用過高問題


  用過GD庫的同學可能都知道,使用imagecreatetruecolor()函數創建一個真彩色的畫布是第一步。但是,如果畫布的寬高超過平常的寬高,會帶來極大的內存消耗。比如,一個9600×4800的畫布,會帶來190M的內存消耗。這時,如果服務器的free空間過小,就會導致內存耗盡,出現各種報錯。本文旨在提供優化服務器時對大圖片的處理方法。

   首先,說下業務場景。我要對用戶上傳的圖片進行裁剪,變成我想要的寬高比。注意,是2:1這種寬高比。 因為用的服務器內存總共只有512M,處理小圖片時還好,但是一旦接觸到4M以上的圖片文件,內存耗盡就成了一個block的點。它會引發nginx報502的錯誤,因為nginx無法從php-fpm那里獲取到相應的值。報錯日志:a client request body is buffered to a temporary file。3119133 recv() failed (104: Connection reset by peer) while reading response header from upstream 這里可以提供下,我使用GD庫對圖片進行處理時的內存占用情況的日志:

 

    

獲取大小內存-1 376.12 kb
獲取大小內存 4.98 mb
#這里使用了imagecreatetruecolor
獲取大小內存2 192.53 mb 圖片width:9600height4800
獲取大小內存3 287.92 mb
獲取大小內存4 287.92 mb
獲取大小內存5 287.92 mb
獲取大小內存6 100.38 mb
獲取大小內存7 104.48 mb
#這里實行了最后一步,釋放內存 獲取大小內存+1 376.21 kb

  可以看到,很明顯的內存占用,關於圖片寬高對內存的影響,網上有個公式:

  

(width*height)* 3 * 圖片位數 //乘以3是因為創建的是rgb色彩模式的圖像,有3個通道

  可以看到,這僅僅是一個4M的圖片,就對服務器提出了將近200M的消耗。當然這里不能僅僅用大小size來衡量,還要加入Width和Height來度量實際的大小。這也是我們處理圖片上傳時,為什么不僅要加入大小的限制 ,還要加入寬高的限制的原因所在。 我的解決方法是使用了一個第三方軟件:imagemagick。 這里我要強推下這個軟件,他可以把你的多張圖片合成一個pdf,也可以將一個pdf轉換成多張圖片,而且可以對圖片增加諸如炭筆,油畫等特效。

   

#CentOs安裝方法   yum install ImageMagick   #測試安裝成功  convert -v

  因為是我個人使用,所以直接在upload的時候實時執行了以下命令。

 

$command = "convert -resize *x* 'images/a.jpg' 'images/a.jpg'"; $result = exec($command, $res, $code); #這里直接使用php的exec命令即可。對參數進行下簡單說明。 #convert imagemagick的轉換命令  #-resize 要執行的命令  #*x* 寬乘以高,這個是小寫的x  #*.jpg 原圖位置 #*.jpg 轉換后圖片的名稱,不改則默認覆蓋原圖

  加上之后,內存的占用日志

  

獲取大小內存-1 384.83 kb 獲取大小內存 384.97 kb 獲取大小內存+1 385.17 kb 執行命令convert -resize 3696x1848! images/20190213094940_940.jpg images/20190213094940_940.jpg #這里在高這里加上!是表示不接受imagemagick默認的等比縮放,強制轉換成這個大小

  可以看到,處理速度和內存占用都降了下來,這一步,將內存的壓力轉換成了Cpu的壓力。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM