2014-12-24 170 views
0

我一直在嘗試從HTML表單獲取文件,然後創建一個新文件,並使用「imagecopyresampled」從中獲取中央方形,擬合X或Y,取決於哪個更小。PHP GD上傳前調整大小/裁剪圖像

不幸的是,我對處理這麼多的圖像和臨時名稱感到有點困惑,我一直有麻煩將文件複製到系統上的用戶文件。 的代碼如下:

所有的
if($_FILES){ 
    $valid = validate_image("avatar"); 

    if ($valid){ 
     list($width, $height, $type) = getimagesize($_FILES['avatar']['tmp_name']); 

     $scale = $width/$height; 
     $pixels = 150; 
     $tmp_name = $_FILES['avatar']['tmp_name']; 

     switch ($type) { 
      case IMAGETYPE_GIF: 
       $source = imagecreatefromgif($tmp_name); 
       break; 

      case IMAGETYPE_JPEG: 
      case IMAGETYPE_JPG: 
       $source = imagecreatefromjpeg($tmp_name); 
       break; 

      case IMAGETYPE_PNG: 
       $source = imagecreatefrompng($tmp_name); 
       break; 
     } 

     $upload = imagecreatetruecolor($pixels, $pixels); 

     //sketchy image math: Get whichever coordinate is smaller and that will be 150 on the thumbnail from top to bottom (or left to right). 
     //Then for the other one you know the size will be 150, but only for the part starting at (Coordinate/2)-SMALLERCOORD/2 to (coord/2)+SMALLERCOORD/2 

     if ($width>$height){ 
      imagecopyresampled ($upload, $source, 0, 0, 0, ($width-$height/2), 150, 150, $height, $height); 
     } else if ($width<=$height){ 
      imagecopyresampled ($upload, $source, 0, 0, 0, ($height-$width/2), 150, 150, $width, $width); 
     } 

     $name = "./users/$id/avatar.png"; 

     imagepng($upload, $tmp_name); 

     if (!(move_uploaded_file($tmp_name, $name))) $fail .= "<h3>ERROR UPLOADING AVATAR. TRY AGAIN LATER OR CONTACT US.</h3><br>"; 
    } 
} 

首先讓我看看,如果我理解這些代碼是如何工作的正確: 我得到的文件,檢查它是否與我的功能有效。然後我得到它的大小和類型。我檢查類型並在服務器內存上創建一個映像,並在另一個空間上創建一個我想要的映像。然後,我實際上覆制了我創建的上傳圖像上調整大小和裁剪後的圖像。 如果我想要,我可以用imagedestroy刪除臨時的「源」圖像,對吧? 接下來,我嘗試從服務器內存的「上傳」圖像中創建一個png文件。 這裏是我認爲我錯了,我不能覆蓋臨時文件,我可以嗎? 然後我嘗試將圖像臨時圖像放在應該上傳但不起作用的地方。

我是否正確?我怎樣才能解決這個問題? 感謝您的關注。

回答

0

因此,在網上搜索了很多後,我發現最大的問題是運行apache(www-data)的用戶。

因此我輸入了/ etc/apache2/envvars並將APACHE_RUN_USER更改爲該文件夾的所有者。 然後我不得不在/ etc/lib/php5上做一個chown,以便會話可以堅持/與新用戶一起工作。

因此,我現在能夠訪問該文件夾,以便服務器能夠在其上編寫和修改。 然後我加入這部分代碼:

$dir = "./users/$id/"; 
$oldumask = mask(0); 
mkdir ("$dir"); 
chmod("$dir", 0750); 
umask($oldumask); 

將其加入右側創建PNG圖像之前。 然後我刪除了「move_uploaded_file」的代碼,只是使用的imagepng功能雅各布Budin建議:

if(!imagepng($upload, $name)) $fail .= "<h3>ERROR!<h3><br>"; 

這解決一切(但事實證明,裁剪代碼是錯誤的,但是這是不相關)。 我仍然不是100%確定GD/PHP如何處理圖像,但這是有效的。 謝謝你和聖誕快樂人人。

0

有關縮略圖生成的邏輯不正確,但更緊迫的問題是保存圖像文件。您試圖保存在文件系統的根目錄(/users/$id/avatar.png),可能沒有這樣做的權限。

儘管您可以保存回上傳路徑,但這不是必需的。在imagepng中,只需將文件保存到您的目的地(例如,/var/web/app/public/uploads/$id/avatar.png)。您還可以使用魔術常數__DIR__指定執行相關PHP文件的路徑。

就裁剪而言,考慮使用預先構建的函數或庫來生成縮略圖。我可以在這裏複製一些代碼,但其他人已經毆打這個問題很多次(並解決了其他潛在問題,如透明度)。您可以在imagecopyresampled上查看文檔(和用戶意見),或使用複雜的庫(如Imagine)。

+0

我的錯誤。它不是「/users/$id/avatar.png」。編輯代碼時,我刪除得太多了,它應該是相對於PHP文件的路徑。 「./users/$id/avatar.png」。因此,PHP代碼所在的同一目錄中的用戶文件夾。 –