ФорумПрограммированиеПыхнуть хотите?Готовые решения → Изменение размеров изображения

Изменение размеров изображения

  • Timur

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

    Spritz Март 6, 2008, 6:13 п.п.

    [size=16pt]formatImage[/size]

    bool formatImage ( string srcFile [, string dstFile [, int dstWidth [, int dstHeight]]] )

    (PHP >= 4.3.0, GD 2.0)
    Изменения типа (GIF, JPEG, PNG) и размеров изображения.

    [size=13pt]Список параметров[/size]

    srcFile - путь к файлу с исходной картинкой. Единственный обязательный параметр.
    dstFile - путь к файлу для нового изображения. Его тип определяется расширением файла (если расширение отсутсвует, тип останется без изменений). Если не указывать этот параметр (или указать значение NULL), картинка, в том же формате, что и исходная, будет отправлена в браузер с соответствующими HTTP-заголовками.
    dstWidth - ширина новой картинки.
    dstHeight - высота новой картинки.


    Если указать только ширину (высоту), то высота (ширина) будет расчитана в соответствии с пропорциями исходного изображения. Если вообще не указывать этих параметров, размеры останутся прежними.
    Функция генерирует ошибки (предупреждения) уровня E_USER_WARNING если
    - не найден файл (или недоступен для чтения) файл srcFile;
    - тип изображения не поддерживается;
    - размеры указаны некорректно.

    [size=13pt]Возвращаемые значения[/size]

    Возвращает TRUE при успешном завершении и FALSE в случае ошибки.

    [size=13pt]Код[/size]
    function formatImage($srcFile, $dstFile = null, $dstWidth = null, $dstHeight = null)
    {
    if (! is_readable($srcFile)) {
    trigger_error("File $srcFile is not readable or not exists", E_USER_WARNING);
    return false;
    }
    list($srcWidth, $srcHeight, $type) = getImageSize($srcFile);
    switch ($type) {
    case IMG_GIF:
    $srcImage = imageCreateFromGif($srcFile);
    break;
    case IMG_JPG:
    $srcImage = imageCreateFromJpeg($srcFile);
    break;
    case IMG_PNG:
    $srcImage = imageCreateFromPng($srcFile);
    break;
    default:
    trigger_error("Invalid image type of '$srcFile'", E_USER_WARNING);
    return false;
    }
    if (isset($dstWidth) || isset($dstHeight)) {
    if (! isset($dstHeight)) {
    $dstHeight = round($dstWidth / ($srcWidth / $srcHeight));
    } elseif (! isset($dstWidth)) {
    $dstWidth = round($dstHeight / ($srcHeight / $srcWidth));
    }
    if ($dstWidth < 1 || $dstHeight < 1) {
    trigger_error("Invalid image dimensions", E_USER_WARNING);
    return false;
    }
    $dstImage = imageCreateTrueColor($dstWidth, $dstHeight);
    imageCopyResampled($dstImage, $srcImage, 0, 0, 0, 0,
    $dstWidth, $dstHeight,
    $srcWidth, $srcHeight);
    } else {
    $dstImage = $srcImage;
    }
    if (empty($dstFile)) {
    $mime = image_type_to_mime_type($type);
    header("Content-Type: $mime");
    } else {
    $ext = strToUpper(pathInfo($dstFile, PATHINFO_EXTENSION));
    if ($ext == 'GIF' || $ext == 'JPEG' || $ext == 'JPG' || $ext == 'PNG') {
    $type = constant("IMG_$ext");
    }
    }
    switch ($type) {
    case IMG_GIF:
    if ($dstFile) {
    imageGif($dstImage, $dstFile);
    } else {
    imageGif($dstImage);
    }
    break;
    case IMG_JPG:
    if ($dstFile) {
    imageJpeg($dstImage, $dstFile);
    } else {
    imageJpeg($dstImage);
    }
    break;
    case IMG_PNG:
    if ($dstFile) {
    imagePng($dstImage, $dstFile);
    } else {
    imagePng($dstImage);
    }
    break;
    }
    imageDestroy($dstImage);
    imageDestroy($srcImage);
    return true;
    }


    [size=13pt]Примеры[/size]

    a) Создание файл [tt]out.gif[/tt] с GIF-изображением, 200x100, из JPEG-картинки [tt]in.jpg[/tt]:
    formatImage('in.jpg', 'out.gif', 200, 100);


    b) Отправка в браузер изображение из [tt]in.jpg[/tt] с высотой 100px и соответствующей шириной:
    formatImage('in.jpg', null, null, 100);


    c) Изменение типа картинки:
    formatImage('in.jpg', 'out.png');
  • md5

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

    Spritz Март 6, 2008, 6:25 п.п., спустя 11 минут 32 секунды

    я думаю, это больше как готовое решение, нежели статья
    все умрут, а я изумруд
  • kendo

    Сообщения: 446 Репутация: N Группа: Адекваты

    Spritz Март 7, 2008, 11:15 д.п., спустя 16 часов 50 минут 8 секунд

    По-моему, надо добавлять отдбельно возможность масштабирования изображения, т.е. если ширина или высота не заданы, то сохранять их как есть.
  • Timur

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

    Spritz Март 7, 2008, 6:26 п.п., спустя 7 часов 10 минут 52 секунды

    KENDO, ну ведь так и есть :) ширину и высоту можно не указывать:
    if (empty($dstWidth) && empty($dstHeight)) {
    $dstWidth = $srcWidth;
    $dstHeight = $srcHeight;
  • adw0rd

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

    Spritz Март 12, 2008, 4:58 д.п., спустя 4 дня 10 часов 31 минуту

    Timur, добавь в описание: что если оставить пустым аргумент "dstFile", то вывод будет производиться в основной поток. Желательно еще добавить объявление заголовков соответствующего миме-типа файла :)
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Timur

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

    Spritz Март 12, 2008, 4:38 п.п., спустя 11 часов 40 минут 26 секунд

    ok, просто изначально вывод в браузер не предусматривался, но раз так - переделал функцию и описание.
  • adw0rd

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

    Spritz Март 12, 2008, 7:36 п.п., спустя 2 часа 57 минут 32 секунды


    case IMG_PNG:
    if ($dstFile) {
    imagePng($dstImage, $dstFile);
    } else {
    imagePng($dstImage);
    }
    break;
    }

    оставь просто:

    case IMG_PNG:
    imagePng($dstImage, $dstFile);
    break;
    }

    код короче будет, тоже касательно JPEG и GIF
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • adw0rd

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

    Spritz Март 12, 2008, 7:42 п.п., спустя 6 минут 56 секунд


    $mime = image_type_to_mime_type($type);
    header("Content-Type: $mime");

    Мимешку мона дернуть было в самом начале, с помощью "getImageSize".
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Animator

    Сообщения: 194 Репутация: N Группа: Кто попало

    Spritz Апрель 16, 2008, 12:26 п.п., спустя 34 дня 15 часов 43 минуты

    а где указывать качество jpg файла?
  • Timur

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

    Spritz Апрель 16, 2008, 1:08 п.п., спустя 41 минуту 22 секунды

    imageJpeg($dstImage, $dstFile, 75); // третий аргумент - качество


    можно добавить ещё один параметр в функцию, я этого делать не стал т.к. рассчитана она кроме jpeg, так же на png и gif
  • Animator

    Сообщения: 194 Репутация: N Группа: Кто попало

    Spritz Апрель 16, 2008, 4:25 п.п., спустя 3 часа 17 минут 38 секунд

    спасибо за скрипт, он мне очень помог
  • Lorado

    Сообщения: 3 Репутация: N Группа: Кто попало

    Spritz Апрель 23, 2008, 2:52 п.п., спустя 6 дней 22 часа 26 минут

    Timur, спасибо за скрипт, но тут у меня небольшая неувязочка. Я не знаю, наверно у меня с сервером что-то…..
    Решил загрузить фотку весом 832 Кб размером 2272 х 1704….вот такая ошибка получается
    Allowed memory size of 8388608 bytes exhausted (tried to allocate 9088 bytes)
    и далее указывает вот на эту строку (в твоём скрипте 13 строка)
    $srcImage = imageCreateFromJpeg($srcFile);


    Что делать? Помогите. Заранее благодарен.
  • Timur

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

    Spritz Апрель 23, 2008, 6:04 п.п., спустя 3 часа 11 минут 27 секунд

    Не хватает памяти. Попробуй увеличить значение memory_limit.
    ini_set('memory_limit', '16M');


    если не поможет, возможно придется ставить ограничение на размеры загружаемого изображения. Подсчитать, сколько картинка будет занимать в памяти можно с помощью формулы:
    ширина * высота * число_каналов * бит_на_канал / 8
    (все эти параметры можно получить функцией getimagesize())
  • Lorado

    Сообщения: 3 Репутация: N Группа: Кто попало

    Spritz Апрель 23, 2008, 9:57 п.п., спустя 3 часа 53 минуты 23 секунды

    Спасибо. С помощью увеличения memory_limit все работает отлично! Правда пришлось увеличить до 32М…. :) Но работает отлично.

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