Главная    Реклама    Об авторе    Muzzлог Зарубина

Загрузка и масштабирование изображений в php

04.07.2008 от Андрей Зарубин

Наверное, многие разработчики web-приложений сталкивались с необходимостью написания скрипта, который бы загружал на сервер графические файлы (изображения). Реализовать это достаточно просто.

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

Методов, по которым строятся иконки несколько.

Первый:
иконка создается путем вырезания центральной части (с заранее заданными размерами) изображения. Например, если исходное изображение имеет линейные размеры 500×500 пикселей, мы можем вырезать центральную область (зачастую именно там основное смысловое содержание картинки) размером 100×100 пикселей. Но мне этот метод не очень нравится, потому что не всегда можно угадать и вырезать фрагмент, который будет плохо передавать содержание исходной картинки. К слову: подобный метод, по моим наблюдениям, применяется в сервисе знакомств mamba.ru ;)

Второй:
иконка создается путем пропорционального уменьшения линейных размеров изображения до (не более) нужных. Этот метод немного сложнее, ведь изображения могут быть разными (горизонтальными, вертикальными, квадратными), а уменьшать их нужно так, чтобы сохранить пропорции, иначе получится искаженная иконка. Пропорции высчитываются из исходных линейных размеров изображения, для этого нужно наибольший исходный размер (для горизонтальных изображений это ширина, а для вертикальных — высота) поделить на установленную нами максимальную ширину (высоту). Далее, чтобы получить линейные размеры уже преобразованного изображения, нужно наименьший исходный размер разделить на полученное соотношение. Округленный до целого результат и будет преобразованным первым линейным размером. А второй линейный размер (ширина или высота) будет равен ранее установленному нами максимальному значению.

Например, если изображение имеет линейные размеры 800×400 пикселей, а максимальная ширина (изображение горизонтальное) равна, допустим, 125 пикселей, то соотношение будет равно 800/125=6,4. Следовательно, ширина изображения на выходе будет 125 пикселей (изображение горизонтальное), а высота будет равна 400/6,4=62 пикселя. В итоге результирующее изображение будет иметь линейные размеры 125×62 пикселей. Если же исходное изображение было вертикальное и имело линейные размеры 400×800 пикселей, то его линейные размеры на выходе были бы 62×125 пикселей. Так можно передать всю картинку полностью, ничего не вырезая. Этот метод, например, применяется на picasa.google.com

Итак, вот что я написал на php (скрипт по загрузке и масштабированию изображений)

Примечание: всякие (безусловно необходимые) проверки на тип файла, размер и все остальное я умышленно опустил.

$w = 125; // Максимальная ширина (высота) конечного файла
$q = 100; // Качество jpeg изображения

$file = $_FILES["yourfile"]["name"]; // Записываем содержимое массива
                                               // $_FILES в $file

$src = imagecreatefromjpeg($_FILES["yourfile"]["tmp_name"]); // Создаем временный
                                                           // файл
$w_src = imagesx($src); // Определяем его линейный размер по горизонтали (ширина)
$h_src = imagesy($src); // Определяем его линейный размер по вертикали (высота)

$dir = "$DOCUMENT_ROOT/images/"; // Папка, куда будет записан
                                                 // уже преобразованный файл

$path = "$dir$file"; // Полный путь к файлу (включая и его имя)

if ($w_src != $w)  // Проверяем не равна ли уже
                         //исходная ширина необходимой нам
  {
   if ($w_src > $h_src) // Если изображение горизонтальное
     {
      $ratio = $w_src/$w; // Считаем соотношение пропорций
      $w_dest = $w; // Конечная ширина будет равна максимальной
      $h_dest = round($h_src/$ratio); // Считаем конечную высоту
     }
   elseif ($h_src > $w_src) // Если изображение вертикальное
     {
      $ratio = $h_src/$w; // Считаем соотношение пропорций
      $h_dest = $w; // Конечная высота будет равна максимальной
      $w_dest = round($w_src/$ratio); // Считаем конечную ширину
     }
   else // Если изображение квадратное
     {
      $w_dest = $w; // Подставляем максимальные значения
      $h_dest = $w;
     }
   $dest = imagecreatetruecolor($w_dest,$h_dest); // Создаем пустое изображение
   imagecopyresampled($dest, $src, 0, 0, 0, 0, $w_dest, $h_dest, $w_src, $h_src);
   // Преобразуем исходное изображение в конечное (с новыми размерами).
   // Функция использует ресемплинг, поэтому изображение будет лучшего
   // качества, чем если использовать вместо imagecopyresampled функцию
   // imagecopyresized
  }
else
  {
   $dest = imagecreatefromjpeg($_FILES["yourfile"]["tmp_name"]);   
   // Если исходная ширина равна нужной нам на выходе, то просто
   // создаем временный файл без преобразований
  }
if (!file_exists ("$path")) // Проверяем не существует ли уже файл
  {
   $res = imagejpeg($dest,"$path",$q); // Копируем файл в папку
   if ($res) // Если скопировано успешно, выдаем сообщение об успехе
     {
      echo “Файл закачан!”;
     }
   else // Если не скопировано, то выдаем сообщение об ошибке
     {
      echo “Ошибка записи файла!”;
     }
   imagedestroy($dest); // Освобождаем память
   imagedestroy($src);
}

Критику в студию :)
__

Хороший туроператор по Кипру — самое время отдохнуть

» Abonner au RSS! «

Рубрики: php |

Комментарии (12)

  1. Юлия пишет:

    Реально понимаю, что человек, практически не знакомый с компьютером может просто не разобраться в этих программах. Хорошо было бы опубликовать подробную статью, с пошаговым описанием. Я вот встречала нечто подобное у Небомжа, но вот хоть убейте меня, сейчас не могу вспомнить, где именно. Эх, жаль…

  2. Андрей Зарубин пишет:

    Ну, кому надо, тот разберется ;) А кто не поймет пропустит… Вообще, подробных статей на эту тему довольно много.

  3. Природа пишет:

    Статей много небывает))в каждой что нибудь да упустят))

  4. cretifka пишет:

    Друган дал ссылку, я обычно подобное не читаю, но не пожалел!

  5. Клим пишет:

    Я бы покитиковал, еслм бы был стоящик кодером, а вообще - задача очень не простая, насколько я знаю.

  6. Андрей Зарубин пишет:

    Клим, ссмотря с чем сравнивать. Если сделать очень клево - то непросто, если так себе - то просто.

  7. Kapinus пишет:

    Ендрю - молодец, повернулся к читателю лицом. Когда по пиву епнем?

  8. vit пишет:

    а для чего такие сложности? зачем изобретать велосипед с квадратными колесами? Не проще сразу же уменьшить изображение не на число, а на процент?

  9. Андрей Зарубин пишет:

    vit, разверните мысль :)

  10. Гость пишет:

    Верноятно, vit o imagecopyresampled и imagecopyresized. Он просто не доразворачивал Вашу, Андрей, мысль дальше первых строк :)

  11. Эдуард пишет:

    >всякие (безусловно необходимые) проверки на тип файла, размер и все остальное я умышленно опустил.

    И очень зря. Об этом нужно писать подробнее, т.к. информации хватает.
    Сатья - для общего развития. И все же :) СПАСИБО!

  12. Андрей Зарубин пишет:

    Статья-то, конечно, для общего развития, я и не настаиваю на чем-то большем…

Оставить комментарий