За последние 24 часа нас посетили 17483 программиста и 1690 роботов. Сейчас ищут 965 программистов ...

Imagick и base64/BLOB

Тема в разделе "PHP для новичков", создана пользователем Sergey_Tsarev, 23 ноя 2017.

  1. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Всем привет!
    Проблема такая:
    От клиента мне приходит файл в base64 и список параметров. Файл должен быть изображением. На JS я это конечно проверяю, но естественно эту проверку можно обойти.
    Далее файл и параметры отправляются в обработчик.

    PHP:
    1. list($type, $data) = explode(';', $image[0]);
    2. list(, $data)      = explode(',', $data);
    3. $data = base64_decode($data);
    Потом мне нужно обработать файл с помощью Imagick (ресайз, поворот, масштабирование, фильтры и т.п.).

    Читаем файл:

    PHP:
    1. $im = new \Imagick();
    2. $im->readImageBlob($data);
    Если пришло изображение, то всё работает. Если же отправить, например текстовый файл, то выдаёт ошибку:

    NoDecodeDelegateForThisImageFormat `' @ error/blob.c/BlobToImage/355

    Собственно вопрос: как проверить, что файл является картинкой и избежать ошибок. Также хотелось бы обезопасить себя от вредоносного кода. На GD я просто пересохранял полученный файл, а вот с Imagick не приходилось работать. Что посоветуете?
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Ловить ImagickException
     
  3. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    @Sergey_Tsarev а что делаете если не секрет??) я недавно похожее делал только с GD)) и предстоит дальше развивать - тоже делать переворачивание, обрезание и т.п.)
     
  4. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @Алекс8, загрузчик фото. Я уже писал тут про это. Клиент выбирает какие изображения загрузить. На клиенте создаются миниатюры в canvas. Так же клиент может задать параметры обработки фото - поворот, обрезка, наложение фильтров. Файлы отправляются на сервер только после отправки формы. Отправляется массив, примерно вот такой:

    PHP:
    1. $array =
    2. [
    3.    'image_1' =>
    4.       [
    5.          'image' => 'строка в base64',
    6.          'param' =>
    7.             [
    8.                'rotate' => 90,
    9.                'crop' => [135,260],
    10.                'filters' => ['sepia', 'saturation', 'brightess'],
    11.             ],
    12.       ],
    13. ];
    Ну, а в обработчике соответственно файл редактируется согласно заданным параметрам и сохраняется в определенную папку.
    Чем мне нравится такой подход по сравнению с ajax загрузкой:
    - Клиент может загрузить 10 фотографий, а потом решит 5 из них удалить. Соответственно напрасно будем нагружать сервер загрузкой ненужных изображений + расходовать трафик пользователя. А если учесть, что скорость мобильного интернета зачастую оставляет желать лучшего, то и будем заставлять пользователя ждать пока загрузятся выбранные им изображения.
    - Так как все манипуляции по загрузке и редактированию изображений происходят на клиенте, на сервер отправляются уже только необходимые данные. Соответственно снижается нагрузка на сервер и мы избегаем лишних манипуляций. Единственное после отправки формы клиенту приходится ждать пока загрузятся все изображения и только после этого произойдёт отправка формы. Но я сделал строку состояния процесса загрузки файлов и отправки формы - так, что клиент понимает, что его комп/браузер не завис. А во-вторых клиент может спокойно отойти от компа, так как основная работа выполнена и для последующих манипуляций его участие не требуется :)
     
  5. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Sergey_Tsarev я на сколько помню я линк на файл имагику скармливаю, а на получение файла можно посмотреть какое расширение у него и так определить чё это картинка или нет.
     
  6. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    @askanim, расширение файла - сугубо лично дело того, кто, или что этот файл создал(о) :D
    @Sergey_Tsarev, вот инструмент для определения типа изображения: int exif_imagetype(string $filename)
     
    Maputo нравится это.
  7. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.866
    Симпатии:
    753
    Адрес:
    Татарстан
    он не файл получает - а base64
     
  8. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    а почему бы не получать файл, зачем получать base64 ?
    --- Добавлено ---
    изначально то это полюбому файл, зачем приводить его к base64?
     
  9. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Кстати, да... можно, конечно, сохранить в файл и проверить, но...
    Вот ещё вариант решения
     
  10. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
  11. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Sergey_Tsarev кстати читал про конвас, говорят он затупок ещё тот. ЛУчше самому нативно на js написать для обрезки картинки
     
  12. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Sergey_Tsarev и вернёмся к нашим баранам. Я тоже так делаю! Обрезаю картинки у себя в движке! И вот что я вам скажу изначально я принимаю на сервере файл с которым потом работаю сохраняю его, потом его гружу в имагик там обрезаю и сохраняю его.
    --- Добавлено ---
    @Sergey_Tsarev если вы делаете по другому вы что-то делаете не правильно.
     
  13. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Каким образом вы его принимаете?
     
  14. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Sergey_Tsarev в $_FILES отправляю и координаты которые режу в посте отправляю.
    --- Добавлено ---
    а там уже на php режу как надо
     
  15. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Можно поподробнее, если не сложно :)
     
  16. Maputo

    Maputo Активный пользователь

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Sergey_Tsarev нравится это.
  17. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    Вот! Это, то что нужно!
     
  18. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    куда подробней тебе ещё, print_r($_FILES) сделай и всё поймёшь, как отправить file ? Ложишь в инпут файл забираешь его в formData
    --- Добавлено ---
    и отправляешь его аяксом на сервер в чём проблема. А там в глобальном массиве $_FILES он уже будет если правильно всё отправил.
     
    Sergey_Tsarev нравится это.
  19. Sergey_Tsarev

    Sergey_Tsarev Активный пользователь

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @askanim, ну я о том и спрашивал) я думал о таком варианте, что бы загружать файлы аяксом после нажатия на submit. В общем-то не в том дело, каким способом отправляются файлы на сервер. Меня больше интересует можно ли в Imagick пересохранить картинку как в GD? Или сохранять её при помощи GD, а редактировать уже при помощи Imagick?
     
  20. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    @Sergey_Tsarev Ты когда ложишь картинку в имагик на выхлопе ты можешь получить блоб, и сохраняешь его в файл примерно вот так это происходит:
    PHP:
    1. file_put_contents ([file_path], $image->getImageBlob());
    --- Добавлено ---
    А ложится в имагик вот так
    PHP:
    1. $image = new \Imagick(realpath([file_path]));
    --- Добавлено ---
    Пересохранить можно, но не так как в гд, в гд ты конкретно указываешь метод формата сохранения. А здесь ты сам в какой формат файла запишешь в тот и запишешь.
     
    Sergey_Tsarev нравится это.