Прикреплённые изображения и их вывод
Прикреплённые к экземплярам моделей изображения нужны для программной обработки и вывода изображений. Применение очень обширное: аватары, логотипы для товаров и каталогов, разные галлереи и слайдеры, и ещё много где.
Идея у данных изображений такая:
- во первых, привязываем к модели изображение и можем его вызывать в любом месте;
- во вторых, загружаем изображение и можем его выводить в любых размерах, соблюдая правила оптимизации.
В общем, это очень удобно для программирования.
Содержание:
# Связи для изображений
В Winter CMS изображения для моделей задаются при помощи связей. Это функционал любимого многими программистами php-фреймворка Laravel.
Документация на оф. сайте: File Attachments
Первым делом нужно в php-файл модели добавить связи. Для одного изображения связь задаётся так:
public $attachOne = [
'logo' => \System\Models\File::class,
];
Свойство $attachOne это массив, поэтому для модели можно добавить сколько вам пожелается привязанных изображений.
Теперь чтобы загрузить изображение с бекенд-части сайта, нужно добавить поле в файл fields.yaml которое выведет форму для загрузки:
fields:
logo:
label: Логотип
mode: image
prompt: 'Загрузите логотип'
imageWidth: '200'
imageHeight: '135'
useCaption: true
thumbOptions:
mode: crop
extension: auto
span: auto
type: fileupload
Связь для нескольких изображений задаётся по такому же принципу через $attachMany:
public $attachMany = [
'gallery' => \System\Models\File::class,
];
Поле с формой для загрузки:
gallery:
label: Галерея
mode: image
imageWidth: '100'
imageHeight: '80'
useCaption: true
thumbOptions:
mode: crop
extension: auto
span: auto
type: fileupload
Как видим, поля что для одиночной, что для множественной загрузки изображений - одинаковые и отличаются только названием идентификатора.
# Вывод изображений
Получить путь к оригиналу загруженного изображения можно при помощи метода getPath(). Примеры:
echo $model->logo->getPath();
В HTML вывести изображение можно при помощи твига:
<img src="{{ model.logo.getPath() }}">
Для вывода изображений из множественной связи используем цикл:
foreach ($model->gallery as $photo) {
echo $photo->getPath();
}
В HTML:
{% for photo in model.gallery %}
<img src="{{ photo.getPath() }}">
{% endfor %}
Метод getLocalPath возвращает абсолютный путь загруженного файла в локальной файловой системе.
echo $model->logo->getLocalPath();
Чтобы вывести содержимое файла напрямую, используйте метод output, который будет включать в себя необходимые заголовки для загрузки файла:
echo $model->logo->output();
# Размеры изображения
Размер изображения можно изменить с помощью метода getThumb(). Например нам нужно вывести изображение размером 300×200px, тогда делаем так:
для PHP
echo $model->logo->getThumb(300, 200, ['mode' => 'exact']);
для HTML
<img src="{{ model.logo.thumb(300, 200, {'mode':'exact'}) }}">
Метод getThumb принимает 3 параметра - ширину изображения, высоту изображения и параметр options. Для options поддерживаются следующие параметры:
| Настройка | Описание |
|---|---|
| mode | auto, exact, portrait, landscape, crop, fit. По умолчанию: auto |
| quality | Качество изображения. Настройка позволяет уменьшать весь изображения. Имеет значения от 0 до 100. По умолчанию: 90 |
| interlace | boolean: false (по умолчанию), true |
| extension | auto, jpg, webp, png, gif. По умолчанию: jpg |
Опция mode позволяет указать каким образом следует изменить размер изображения. Для неё доступны следующие режимы:
autoбудет автоматически выбирать междуportraitиlandscapeна основе ориентации изображения;exactизменяет размеры до точных размеров без сохранения соотношения сторон;portraitизменит размер до заданной высоты и адаптирует ширину, чтобы сохранить соотношение сторон;landscapeизменит размер до заданной ширины и адаптирует высоту, чтобы сохранить соотношение сторон;cropбудет обрезать до заданных размеров после подгонки как можно большей части изображения внутри этих;fitбудет соответствовать изображению внутри заданных максимальных размеров, сохраняя соотношение сторон.
Вывод изображения с применением параметров:
<img src="{{ model.avatar.getThumb(100, 100, {'mode':'exact', 'quality': 80, 'extension': 'webp'}) }}" alt="Описание изображения">
# Моды для изображений
Чтобы понять как работают моды в Winter CMS, давайте возьмём в качестве модели фото вертикальной (портретной) ориентации молодого привлекательного мужчины и посмотрим как же работают моды в настройках:
Это оригинальное изображение портретной ориентации с изначальным размером 200×338px.
Для полноты картины возьмём ещё одно изображение с горизонтальным направлением:
У этого изображения горизонтальная ориентация с размером 300×111px.
Оба этих изображения буду выводить в HTML размером 200×135px следующим способом:
<img src="{{ model.img.thumb(200, 135, {'mode':'название_мода'}) }}">
Чтобы отчётливо было видно размеры изображений, через css добавлю им рамку и небольшую тень.
mode: auto
Мод auto автоматически выбирает между модами portrait и landscape на основе ориентации изображения. Вывожу каждое изображение следующим кодом:
<img src="{{ item.logo.thumb(200, 135, {'mode':'auto'}) }}">
в результате получаем такую картину:
Мод сохранил ориентацию изображений, при этом для портретной ориентации он выполнил заданный размер в высоту (135px), а ширину подогнал пропорционально исходя от оригинального изображения. Для второго изображения альбомной ориентации мод выполнил заданную ширину (200px), а высоту подогнал пропорционально.
mode: exact
exact изменяет размеры до точных размеров без сохранения соотношения сторон
<img src="{{ item.logo.thumb(200, 135, {'mode':'exact'}) }}">
Как видно, оба изображения стали заданной ширины 200×135px, при этом изначальное соотношение сторон не сохранилось, а сами изображения потнрпели деформации.
mode: portrait
portrait изменит размер до заданной высоты и адаптирует ширину, чтобы сохранить соотношение сторон
<img src="{{ item.logo.thumb(200, 135, {'mode':'portrait'}) }}">
Здесь мод portrait в обоих случаях сделал изображения высотой 135px, а ширину подогнал пропорционально от оригинала изображения.
mode: landscape
landscape изменит размер до заданной ширины и адаптирует высоту, чтобы сохранить соотношение сторон из оригинала
<img src="{{ item.logo.thumb(200, 135, {'mode':'landscape'}) }}">
Мод landscape в обоих случаях сделал изображения шириной 200px, а высоту подогнал в соотношении сторон из оригинала изображения.
mode: crop
crop обрезает изображение до заданных размеров
<img src="{{ item.logo.thumb(200, 135, {'mode':'crop'}) }}">
Здесь мы видим, что мод crop сделал оба изображения заданного размера 200×135px. При этом он не стал подгонять соотношения сторон, а просто обрезал их под заданный размер. Саму обрезку он сделал из центра изображений.
mode: fit
И последний мод который осталось рассмотреть - это fit. Выводим и смотрим на результат:
<img src="{{ item.logo.thumb(200, 135, {'mode':'fit'}) }}">
Видно что fit подогнал изображения под максимальные из заданных размеров, сохраняя соотношение сторон. То есть. исходя из наших условий, изображение не может быть шириной более чем 200px, а высотой более чем 135px.
# Удалить эскизы
Удалить все созданные эскизы в каталоге загрузки можно с помощью команды:
php artisan winter:util purge thumbs
*** Войдите чтобы писать комментарии.