Обработка изображений в Hugo

2021.06.22, обновлено 2023.01.03. Теги: Hugo

Интересным открытием оказалась система обработки изображений в Hugo, мне она очень понравилась: она довольно мощная и функциональная, но при этом с простым интерфейсом, который позволяет настраивать её несколькими строками кода. Кроме того, она поддерживает WebP - формат изображений, который мне также очень нравится.

Для вставки изображений я сделал следующий шорткод:

layouts/shortcodes/img.html

{{ $original := $.Page.Resources.GetMatch (.Get 0) }}
{{ $optimized := $original.Fit "896x3072 webp" }}

<figure>
	<a href="{{ $original.RelPermalink }}" target="_blank">
		<picture>
			<source type="image/webp" srcset="{{ $optimized.RelPermalink }}">
			<img src="{{ $original.RelPermalink }}" alt="{{ .Get 1 }}"
				 width="{{ $optimized.Width }}" height="{{ $optimized.Height }}" />
		</picture>
	</a>
	<figcaption>{{ .Get 1 }}</figcaption>
</figure>

Использование внутри Markdown

{{< img "myimage.png" "Моя любимая картинка" >}}

Суть работы

  1. В качестве первого аргумента берётся изображение из каталога страницы (Page Resource)
  2. Если изображение шире определённого значения, оно масштабируется до этой ширины с сохранением пропорций: у меня это значение чуть меньше максимальной ширины текстового блока на странице (896 пикселей).
  3. Оптимизированное изображение сохраняется в формате WebP;
  4. Так как такое ограничение по размеру может быть мало для некоторых изображений, пользователь может открыть нетронутый оригинал в новой вкладке, нажав на картинку;
  5. Оптимизированное изображение показывается в тексте страницы вместе с подписью из второго аргумента шорткода для доступности и случаев, когда изображение не подгружается;
  6. Для старых браузеров, которые не поддерживают WebP и/или тег picture, показывается исходное изображение.

И главное – все трансформации происходят на этапе сборки проекта автоматически, то есть в каталоге с контентом не хранится по две копии одной картинки в разных форматах, что очень удобно и соответствует принципу DRY.

При желании можно аналогичным образом сделать несколько оптимизированных изображений под разные размеры экранов, используя аттрибут media у тега source.

Настройки

По умолчанию качество изображений не самое лучшее, особенно в случаях, когда они масштабируются до нужной ширины.

Изменение настроек в файле config.yaml позволило значительно улучшить внешний вид оптимизированных изображений:

imaging:
  quality: 85 # процентов
  hint: picture
  resampleFilter: Lanczos

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

Результат

На тестовой странице без масштабирования изображений размер изменился следующим образом:

Исходный форматJPEGPNG
Исходный размер15,95 Кб21,33 Кб
Размер WebP4,45 Кб15,95 Кб

Разница невооружённым глазом для меня едва заметна при сравнении рядом.