ФорумПрограммированиеPHP для идиотов → Загрузка изображений, изменение ширины и высоты на лету.

Загрузка изображений, изменение ширины и высоты на лету.

  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 6:58

    Доброго времени суток, ув.форумчане!
    С загрузкой картинок я разобрался, а вот как мне их обрезать налету не как не пойму
    сл. вопросы:
    1. В книге "Разработка web-приложений с помощью php и mysql. Л.Веллинг,Л.Томсон" прочитал как обрезать изображения на лету, но там только для jpeg файлов, вопрос в том, данное действие можно делать только для jpeg'ов? В гугле не чего не нашел :(
    2. Как я понял действия должны выполняться следующим образом:
        2.1загружаем и сохраняем изображение
    $uploaddir = './files/';
    $uploadfile = $uploaddir.basename($_FILES['uploadfile']['name']);

    if (copy($_FILES['uploadfile']['tmp_name'], $uploadfile))
    {
    echo "<h3>Файл успешно загружен на сервер</h3>";
    }
    else { echo "<h3>Ошибка! Не удалось загрузить файл на сервер!</h3>"; exit; }
    echo 'url= <a href="'.$uploadfile.'" title="'.$_FILES['uploadfile']['name'].'">смотреть</a>'

        2.2 Изменяем ширину и высоту(как?)
    вот пример из книги:

     $image = $_REQUEST['image'];
     $max_width = $_REQUEST['max_width'];
     $max_height = $_REQUEST['max_height'];

     if (!$max_width)
       $max_width = 80;
     if (!$max_height)
       $max_height = 60;

     $size = GetImageSize($image);
     $width = $size[0];
     $height = $size[1];

     $x_ratio = $max_width / $width;
     $y_ratio = $max_height / $height;

     if ( ($width <= $max_width) && ($height <= $max_height) ) {
       $tn_width = $width;
       $tn_height = $height;
     }
     else if (($x_ratio * $height) < $max_height) {
       $tn_height = ceil($x_ratio * $height);
       $tn_width = $max_width;
     }
     else {
       $tn_width = ceil($y_ratio * $width);
       $tn_height = $max_height;
     }

     $src = ImageCreateFromJpeg($image);
     $dst = ImageCreate($tn_width,$tn_height);
     ImageCopyResized($dst, $src, 0, 0, 0, 0,
         $tn_width,$tn_height,$width,$height);
     header('Content-type: image/jpeg');
     ImageJpeg($dst, null, -1);
     ImageDestroy($src);
     ImageDestroy($dst);

    дальше вообще не пойму че и как…
        2.3 Опять копируем уже измененное изображение?
        2.4 И выводим информацию о нем?
    PS Заранее благодарен, прошу сильно не пинать, на форуме тему читал
  • Timur

    Сообщения: 1068 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 8:10, спустя 1 час 11 минут 34 секунды

    1) GD поддерживает разные форматы, включая JPEG, GIF, PNG.

    2) вместо [tt]copy[/tt] используй move_uploaded_file
    (Загрузка файлов на сервер)

    3) вместо [tt]imageCopyResized[/tt] используй imageCopyResampled (там же, ниже есть пример ресайза картинки)
    - загружаем изображение из файла (imageLoadCreateFromJpeg)
    - создаем новое изображение ([tt]imageCreateTrueColor[/tt])
    - c помощью [tt]imageCopyResampled[/tt] копируем первое во второе
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 8:37, спустя 27 минут 8 секунд

    а чего это я в мане не найду эту функцию imageLoadFromJpeg
    зато в мановском примере используется эта imagecreatefromjpeg($filename);
    У тебя опечатка, или все так лоадфромжпг надо?
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 8:44, спустя 7 минут 37 секунд

    вот такое когда-то написал и использую ( imagecreatefrom* - справляется с jpg, gif и png. на выходе всегда jpg для простоты)

    /*
    ********************************************************************************
    ** Create thumbnail image and save result to file. Needs GD library!
    ** Thumbnail fits to size. JPEG used for output.
    ** When
    **  $do_cut==true  - fit by short side and cut long side
    **  $do_cut==false - fit into box w/o any cuts
    ********************************************************************************
    */
    function create_thumbnail($orig_fname, $thum_fname, $thumb_width=100, $thumb_height=100, $do_cut=false)
    {
    $rgb = 0xFFFFFF;
    $quality = 80;
    $size = @getimagesize($orig_fname);
    $src_x = $src_y = 0;

    if( $size === false) return false;

    $format = strtolower(substr($size['mime'], strpos($size['mime'], '/')+1));
    $icfunc = "imagecreatefrom" . $format;
    if (!function_exists($icfunc)) return false;

    $orig_img = $icfunc($orig_fname);
    if (($size[0] <= $thumb_width) && ($size[1] <= $thumb_height))
    {
    // use original size
    $width  = $size['0'];
    $height = $size['1'];
    }
    else
    {
    $width  = $thumb_width;
    $height = $thumb_height;

    // calculate fit ratio
    $ratio_width  = $size['0'] / $thumb_width;
    $ratio_height = $size['1'] / $thumb_height;

    if ($ratio_width < $ratio_height)
    {
    if ($do_cut)
    {
    $src_y = ($size['1'] - $thumb_height * $ratio_width) / 2;
    $size['1'] = $thumb_height * $ratio_width;
    }
    else
    {
    $width  = $size['0'] / $ratio_height;
    $height = $thumb_height;
    }
    } else {
    if ($do_cut)
    {
    $src_x = ($size['0'] - $thumb_width * $ratio_height) / 2;
    $size['0'] = $thumb_width * $ratio_height;
    }
    else
    {
    $width  = $thumb_width;
    $height = $size['1'] / $ratio_width;
    }
    }
    }

    $thum_img = imagecreatetruecolor($width, $height);
    imagefill($thum_img, 0, 0, $rgb);
    imagecopyresampled($thum_img, $orig_img, 0, 0, $src_x, $src_y, $width, $height, $size[0], $size[1]);

    imagejpeg($thum_img, $thum_fname, $quality);
    flush();
    imagedestroy($orig_img);
    imagedestroy($thum_img);
    return true;
    }

    resampled дает более качественную картинку, чем resized, но требует заметно бОльшего времени. если функцию использовать непосредственно после загрузки большой картинки, может не хватить дефолтного таймлимита. поэтому я проверяю наличие и создаю превьюшки нужных размеров не в скрипте upload, а в скрипте показа этих превьюшек. проверено временем :)

    p.s. если хочется максимального качества, надо ресамплить в несколько шагов в цикле. так делают в фотошопе когда уменьшают для веба и стараются сохранить максимум деталей. а всякие шарпы - ацкое зло.
    ιιlllιlllι унц-унц
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 8:59, спустя 15 минут

    artoodetoo, щас буду смотреть, то что на выходе jpg это отлично! :) спасибо! Можно будет если что вопросы задавать?
  • mario

    Сообщения: 6067 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 9:04, спустя 4 минуты 14 секунд

    эм, а вот и вопрос, я так понял твой скрипт не заменяет закаченное изображение, обработанным изображением? и каждый раз просто создает новую картинку а потом разрушает?
    а я бы хотел следущего(вот все не как не могу допетлить, это наверное надо поспать :D )
    1. Загружаем изображение
    2. Если изображение меньше требуемых нам размеров, оставляем его как есть, если нет, то обрабатываем его.
    3. И уже сохраняем его в папку /files/images/
    Вот тут я думаю в задаче сразу косяк.
    надо поступить сл.образом
    1. Загружаем изображение
    2. Сохраняем его как есть.
    3. Обрабатываем если необходимо
    4. Перезаписываем.
    Какой ход мыслей правильнее?
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 9:36, спустя 32 минуты 7 секунд


    и каждый раз просто создает новую картинку а потом разрушает?

    разрушается объект "картинка", освобождается память, а файл сохранятся.


    надо поступить сл.образом
    1. Загружаем изображение
    2. Сохраняем его как есть.
    3. Обрабатываем если необходимо
    4. Перезаписываем.
    Какой ход мыслей правильнее?

    а ты посмотри как работает flickr.com — это мировой эталон :) есть оригинальное изображение произвольного размера и несколько предопределенных превьюшек на разные случаи. оригинал они НЕзаменяют.
    логично хранить оригинал, но давать право на его загрузку не всем. а превьюшки пусть смотрят, нежалко.

    edited: моя функция в любом случае создает новый экземпляр файла, даже если уменьшать не требуется. можно считать это недоработкой, а можно сделать вид, что это продуманная фича :) обработанная копия jpeg ВСЕГДА ХУЖЕ ОРИГИНАЛА, а не факт, что мы дадим посетителю доступ к оригиналу. это тебе решать.
    ιιlllιlllι унц-унц
  • Timur

    Сообщения: 1068 Репутация: N Группа: Джедаи

    Spritz 3 апреля 2009 г. 10:11, спустя 35 минут 29 секунд

    а чего это я в мане не найду эту функцию imageLoadFromJpeg

    а её там нет. Но есть imageCreateFromJpeg. Опечатко.
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:30, спустя 3 часа 18 минут 44 секунды

  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:38, спустя 7 минут 58 секунд

    кухня все ваши поделки. любой неплохой парень давно юзает имагик для этих целей :)

    http://www.imagemagick.org/Usage/thumbnails/
    Сапожник без сапог
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:44, спустя 6 минут 10 секунд


    кухня все ваши поделки. любой неплохой парень давно юзает имагик для этих целей :)
    Это точно, одна эта команда http://ru2.php.net/manual/ru/function.imagick-cropthumbnailimage.php заменяет 20 строк кода с алгоритмом вычесления размера, координат области и ресайза превьюхи и 4 строки кода с сохранением нового изображения. ))))))))
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:46, спустя 1 минуту 38 секунд

    AlexB, я о том же
    Сапожник без сапог
  • AlexB

    Сообщения: 4306 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:47, спустя 52 секунды


    AlexB, я о том же
    Ну да, я просто тыкнул в нужную команду
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:50, спустя 3 минуты 39 секунд

    AlexB, не использую пхп екстеншн, так как пока не уверен что он стоит хотя бы на 20% серверов. я неправ? стоит его юзать? а то я всегда через бектипсы имагик юзаю
    Сапожник без сапог
  • artoodetoo

    Сообщения: 5147 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 13:51, спустя 38 секунд

    угу. а фотошоп заменяет все остальное.
    вызывается одной строкой:

    photoshop.exe
    ιιlllιlllι унц-унц

Пожалуйста, авторизуйтесь, чтобы написать комментарий!