Изменение размера изображения PHP - Почему изображение загружается, но не изменяется? - PullRequest
1 голос
/ 12 марта 2010

ФОН
У меня есть скрипт для загрузки изображения. Один, чтобы сохранить исходное изображение и один, чтобы изменить размер изображения. 1. Если размеры изображения (ширина и высота) находятся в пределах максимальных размеров, я использую простое «копирование» непосредственно в папку UserPics. 2. Если исходные размеры больше максимальных размеров, я хочу изменить ширину и высоту, чтобы они были в пределах макс. Они оба загружают изображение в папку, но в случае 2 изображение не будет изменено.

Вопрос * * 1004 Что-то не так с сценарием?
Что-то не так с настройками?

Настройки
Сервер: WAMP 2.0
PHP: 5.3.0
PHP.ini: GD2 включен, память = 128M (пробовал 1000M)
Загружены пробные типы изображений: jpg, jpeg, gif и png (одинаковый результат для всех них)

СЦЕНАРИЙ

if (isset($_POST['adduserpic'])) {  
    // Check errors on file  
    if ($_FILES["file"]["error"] > 0) {  
        echo $_FILES["file"]["error"]." errors<br>";  
    } else {  
        $image =$_FILES["file"]["name"];  
        $uploadedfile = $_FILES["file"]["tmp_name"];  
    //Uploaded image  
    $filename = stripslashes($_FILES['file']['name']);  

    //Read filetype  
    $i = strrpos($filename,".");  
    if (!$i) { return ""; }  
    $l = strlen($filename) - $i;  
    $extension = substr($filename,$i+1,$l);  
    $extension = strtolower($extension);  

    //New picture name = maxid+1 (from database)  
    $query = mysql_query("SELECT MAX(PicId) AS number FROM userpictures");  
    $row = mysql_fetch_array($query);  
    $imagenumber = $row['number']+1;  

    //New name of image (including path)   
    $image_name=$imagenumber.'.'.$extension;    
    $newname = "UserPics/".$image_name;  

    //Check width and height of uploaded image  
    list($width,$height)=getimagesize($uploadedfile);  

    //Check memory to hold this image (added only as checkup)   
    $imageInfo = getimagesize($uploadedfile);   
    $requiredMemoryMB = ( $imageInfo[0] * $imageInfo[1] * ($imageInfo['bits'] / 8) * $imageInfo['channels'] * 2.5 ) / 1024;  
    echo $requiredMemoryMB."<br>";  

    //Max dimensions that can be uploaded  
    $maxwidth = 20;  
    $maxheight = 20;  

    // Check if dimensions shall be original  
    if ($width > $maxwidth || $height > $maxheight) {  
        //Make jpeg from uploaded image  
        if ($extension=="jpg" || $extension=="jpeg" || $extension=="pjpeg" ) {  
            $modifiedimage = imagecreatefromjpeg($uploadedfile);  
        } elseif ($extension=="png") {  
            $modifiedimage = imagecreatefrompng($uploadedfile);  
        } elseif ($extension=="gif") {  
            $modifiedimage = imagecreatefromgif($uploadedfile);  
        }   
        //Change dimensions  
        if ($width > $height) {  
            $newwidth = $maxwidth;  
            $newheight = ($height/$width)*$newwidth;  
        } else {  
            $newheight = $maxheight;  
            $newwidth = ($width/$height)*$newheight;  
        }  

        //Create new image with new dimensions  
        $newdim = imagecreatetruecolor($newwidth,$newheight);  
        imagecopyresized($newdim,$modifiedimage,0,0,0,0,$newwidth,$newheight,$width,$height);  
        imagejpeg($modifiedimage,$newname,60);  

        // Remove temp images  
        imagedestroy($modifiedimage);  
        imagedestroy($newdim);  
    } else {  
        // Just add picture to folder without resize (if org dim < max dim)  
        $newwidth = $width;  
        $newheight = $height;  
        $copied = copy($_FILES['file']['tmp_name'], $newname);  
    }

    //Add image information to the MySQL database  
    mysql_query("SET character_set_connection=utf8", $dbh);  
    mysql_query("INSERT INTO userpictures (PicId, Picext, UserId, Width, Height, Size) VALUES('$imagenumber', '$extension', '$_SESSION[userid]', '$newwidth', '$newheight', $size)") 

Ответы [ 3 ]

0 голосов
/ 12 марта 2010

Вы проверили, что блок изменения размера изображения действительно используется? Рассмотрим также некоторый отладочный вывод. Я не вижу ничего явно неправильного

if ($width > $maxWidth || etc...) {
   echo "Hey, gotta shrink that there image";
   ... do the resizing ...
   $resizedImage = getimagesize($newname);
   var_dump($resizedImage); // see if the new image actually exists/what its stats are
   etc....
} else {
   echo "Woah, that's a small picture, I'll just make a straight copy instead";
}

Возможно, вы также захотите округлить $ newheight / $ newwidth до целочисленных значений. Почти во всех случаях вы получите дробный результат, а у изображений нет дробных пикселей.

Кроме того, у вас есть состояние гонки с генератором идентификационного номера:

$query = mysql_query("SELECT MAX(PicId) AS number FROM userpictures");  
$row = mysql_fetch_array($query);  
$imagenumber = $row['number']+1; 

Рассмотрим случай, когда две загрузки завершаются практически одновременно. Они оба получат один и тот же идентификационный номер (скажем, 25). И тогда, какой бы процесс загрузки не занимал больше времени, он «выиграет» и перезапишет более быстрый.

Попробуйте переписать часть базы данных для использования транзакции, используя следующую логику:

 1. start transaction
 2. insert skeleton record into the db and get its ID
 3. do image processing, copying, saving, etc...
 4. update record with the new image's stats
 5. commit the transaction

Таким образом, транзакция будет «скрывать» запись, так как она еще не зафиксирована, для двух или более одновременных загрузок невозможно получить один и тот же идентификационный номер, и в случае сбоя во время обработки изображения (недостаточно памяти, места на диске, испорченный исходный образ и т. д.) вы просто откатываете транзакцию и убираете беспорядок.

I

0 голосов
/ 13 марта 2010

1) Проверьте разрешения. убедитесь, что ваш каталог UserPics может быть записан пользователем, выполняющим веб-процесс (например, www-данные в системе Debian). Я не знаком с системными разрешениями на окнах для такого рода вещей, но именно это я бы проверил, писал ли я это сам (и у меня есть, и я, вероятно, сделал).

2) Не связано, по сути, но проверить http://sourceforge.net/projects/littleutils/

Я запускаю opt-gif и opt-jpg для всех своих загруженных изображений, чтобы сэкономить дисковое пространство без потерь (моему приложению не нужно то, что потеряно)

0 голосов
/ 12 марта 2010

На первый взгляд, я не вижу ничего плохого в скрипте, но это очень сложно решить без каких-либо результатов теста и отчетов об ошибках.

  1. Вверх error_reporting(E_ALL)

  2. Посмотрите, что $newname установлено на

  3. Посмотрите, что делает команда copy ()

Бьюсь об заклад, вы получаете что-то, когда вы включаете отчеты об ошибках. Кстати, чтобы узнать расширение файла, я бы использовал pathinfo.

...