---
title: "Image Processing"
description: "Resize, crop, rotate, filter, and convert images."
date: 2018-01-24T13:10:00-05:00
categories: ["content management"]
keywords: [resources, images]
weight: 4004
draft: false
toc: true
menu:
docs:
parent: "content-management"
weight: 32
---
## Image Resources
To process an image, you must access the image as either a page resource or a global resource.
### Page Resources
A page resource is a file within a [page bundle]. A page bundle is a directory with an `index.md` or `_index.md` file at its root.
```text
content/
└── posts/
└── post-1/ <-- page bundle
├── index.md
└── sunset.jpg <-- page resource
```
To access an image as a page resource:
```go-html-template
{{ $image := .Resources.GetMatch "sunset.jpg" }}
```
### Global Resources
A global resource is a file:
- Within the `assets` directory, or
- Within any directory [mounted] to the `assets` directory, or
- Located on a remote server accessible via `http` or `https`
```text
assets/
└── images/
└── sunset.jpg <-- global resource
```
To access a local image as a global resource:
```go-html-template
{{ $image := resources.Get "images/sunset.jpg" }}
```
To access a remote image as a global resource:
```go-html-template
{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}
```
## Image Rendering
Once you have accessed an image as either a page resource or a global resource, render it in your templates using the `Permalink`, `RelPermalink`, `Width`, and `Height` properties.
Example 1: Throws an error if the resource is not found.
```go-html-template
{{ $image := .Resources.GetMatch "sunset.jpg" }}
```
Example 2: Skips image rendering if the resource is not found.
```go-html-template
{{ $image := .Resources.GetMatch "sunset.jpg" }}
{{ with $image }}
{{ end }}
```
Example 3: A more concise way to skip image rendering if the resource is not found.
```go-html-template
{{ with .Resources.GetMatch "sunset.jpg" }}
{{ end }}
```
## Image Processing Methods
The `image` resource implements the `Resize`, `Fit`, `Fill`, `Crop`, `Filter`, and `Exif` methods.
{{% note %}}
Metadata (Exif, IPTC, XMP, etc.) is not preserved during image transformation. Use the`Exif` method with the _original_ image to extract Exif metadata from JPEG or TIFF images.
{{% /note %}}
### Resize
Resize an image to the specified width and/or height.
If you specify both width and height, the resulting image will be disproportionally scaled unless the original image has the same aspect ratio.
```go-html-template
{{/* Resize to a width of 600px and preserve aspect ratio */}}
{{ $image := $image.Resize "600x" }}
{{/* Resize to a height of 400px and preserve aspect ratio */}}
{{ $image := $image.Resize "x400" }}
{{/* Resize to a width of 600px and a height of 400px */}}
{{ $image := $image.Resize "600x400" }}
```
### Fit
Downscale an image to fit the given dimensions while maintaining aspect ratio. You must provide both width and height.
```go-html-template
{{ $image := $image.Fit "600x400" }}
```
### Fill
Crop and resize an image to match the given dimensions. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point.
```go-html-template
{{ $image := $image.Fill "600x400" }}
```
### Crop
Crop an image to match the given dimensions without resizing. You must provide both width and height. Use the [`anchor`] option to change the crop box anchor point.
```go-html-template
{{ $image := $image.Crop "600x400" }}
```
### Filter
Apply one or more [filters] to an image.
```go-html-template
{{ $image := $image.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}
```
Write this in a more functional style using pipes. Hugo applies the filters in the order given.
```go-html-template
{{ $image := $image | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}
```
Sometimes it can be useful to create the filter chain once and then reuse it.
```go-html-template
{{ $filters := slice (images.GaussianBlur 6) (images.Pixelate 8) }}
{{ $image1 := $image1.Filter $filters }}
{{ $image2 := $image2.Filter $filters }}
```
### Exif
Provides an [Exif] object containing image metadata.
You may access Exif data in JPEG and TIFF images. To prevent errors when processing images without Exif data, wrap the access in a `with` statement.
```go-html-template
{{ with $image.Exif }}
Date: {{ .Date }}
Lat/Long: {{ .Lat }}/{{ .Long }}
Tags:
{{ range $k, $v := .Tags }}
TAG: {{ $k }}: {{ $v }}
{{ end }}
{{ end }}
```
You may also access Exif fields individually, using the [`lang.FormatNumber`] function to format the fields as needed.
```go-html-template
{{ with $image.Exif }}
{{ with .Date }}- Date: {{ .Format "January 02, 2006" }}
{{ end }}
{{ with .Tags.ApertureValue }}- Aperture: {{ lang.FormatNumber 2 . }}
{{ end }}
{{ with .Tags.BrightnessValue }}- Brightness: {{ lang.FormatNumber 2 . }}
{{ end }}
{{ with .Tags.ExposureTime }}- Exposure Time: {{ . }}
{{ end }}
{{ with .Tags.FNumber }}- F Number: {{ . }}
{{ end }}
{{ with .Tags.FocalLength }}- Focal Length: {{ . }}
{{ end }}
{{ with .Tags.ISOSpeedRatings }}- ISO Speed Ratings: {{ . }}
{{ end }}
{{ with .Tags.LensModel }}- Lens Model: {{ . }}
{{ end }}
{{ end }}
```
#### Exif Variables
.Date
: Image creation date/time. Format with the [time.Format] function.
.Lat
: GPS latitude in degrees.
.Long
: GPS longitude in degrees.
.Tags
: A collection of the available Exif tags for this image. You may include or exclude specific tags from this collection in the [site configuration](#exif-data).
## Image Processing Options
The `Resize`, `Fit`, `Fill`, and `Crop` methods accept a space-separated, case-insensitive list of options. The order of the options within the list is irrelevant.
### Dimensions
With the `Resize` method you must specify width, height, or both. The `Fit`, `Fill`, and `Crop` methods require both width and height. All dimensions are in pixels.
```go-html-template
{{ $image := $image.Resize "600x" }}
{{ $image := $image.Resize "x400" }}
{{ $image := $image.Resize "600x400" }}
{{ $image := $image.Fit "600x400" }}
{{ $image := $image.Fill "600x400" }}
{{ $image := $image.Crop "600x400" }}
```
### Rotation
Rotates an image counter-clockwise by the given angle. Hugo performs rotation _before_ scaling. For example, if the original image is 600x400 and you wish to rotate the image 90 degrees counter-clockwise while scaling it by 50%:
```go-html-template
{{ $image = $image.Resize "200x r90" }}
```
In the example above, the width represents the desired width _after_ rotation.
To rotate an image without scaling, use the dimensions of the original image:
```go-html-template
{{ with .Resources.GetMatch "sunset.jpg" }}
{{ with .Resize (printf "%dx%d r90" .Height .Width) }}
{{ end }}
{{ end }}
```
In the example above, on the second line, we have reversed width and height to reflect the desired dimensions _after_ rotation.
### Anchor
When using the `Crop` or `Fill` method, the _anchor_ determines the placement of the crop box. You may specify `TopLeft`, `Top`, `TopRight`, `Left`, `Center`,`Right`, `BottomLeft`, `Bottom`, `BottomRight`, or `Smart`.
The default value is `Smart`, which uses [Smartcrop] image analysis to determine the optimal placement of the crop box. You may override the default value in the [site configuration](#processing-options).
For example, if you have a 400x200 image with a bird in the upper left quadrant, you can create a 200x100 thumbnail containing the bird:
```go-html-template
{{ $image.Crop "200x100 TopLeft" }}
```
If you apply rotation when using the `Crop` or `Fill` method, specify the anchor relative to the rotated image.
### Target Format
By default, Hugo encodes the image in the source format. You may convert the image to another format by specifying `bmp`, `gif`, `jpeg`, `jpg`, `png`, `tif`, `tiff`, or `webp`.
```go-html-template
{{ $image.Resize "600x webp" }}
```
To convert an image without scaling, use the dimensions of the original image:
```go-html-template
{{ with .Resources.GetMatch "sunset.jpg" }}
{{ with .Resize (printf "%dx%d webp" .Width .Height) }}
{{ end }}
{{ end }}
```
### Quality
Applicable to JPEG and WebP images, the `q` value determines the quality of the converted image. Higher values produce better quality images, while lower values produce smaller files. Set this value to a whole number between 1 and 100, inclusive.
The default value is 75. You may override the default value in the [site configuration](#processing-options).
```go-html-template
{{ $image.Resize "600x webp q50" }}
```
### Hint
Applicable to WebP images, this option corresponds to a set of pre-defined encoding parameters.
Value|Example
:--|:--
`drawing`|Hand or line drawing with high-contrast details
`icon`|Small colorful image
`photo`|Outdoor photograph with natural lighting
`picture`|Indoor photograph such as a portrait
`text`|Image that is primarily text
The default value is `photo`. You may override the default value in the [site configuration](#processing-options).
```go-html-template
{{ $image.Resize "600x webp picture" }}
```
### Background Color
When converting an image from a format that supports transparency (e.g., PNG) to a format that does _not_ support transparency (e.g., JPEG), you may specify the background color of the resulting image.
Use either a 3-digit or a 6-digit hexadecimal color code (e.g., `#00f` or `#0000ff`).
The default value is `#ffffff` (white). You may override the default value in the [site configuration](#processing-options).
```go-html-template
{{ $image.Resize "600x jpg #b31280" }}
```
### Resampling Filter
You may specify the resampling filter used when resizing an image. Commonly used resampling filters include:
Filter|Description
:--|:--
`Box`|Simple and fast averaging filter appropriate for downscaling
`Lanczos`|High-quality resampling filter for photographic images yielding sharp results
`CatmullRom`|Sharp cubic filter that is faster than the Lanczos filter while providing similar results
`MitchellNetravali`|Cubic filter that produces smoother results with less ringing artifacts than CatmullRom
`Linear`|Bilinear resampling filter, produces smooth output, faster than cubic filters
`NearestNeighbor`|Fastest resampling filter, no antialiasing
The default value is `Box`. You may override the default value in the [site configuration](#processing-options).
```go-html-template
{{ $image.Resize "600x400 Lanczos" }}
```
See [github.com/disintegration/imaging] for the complete list of resampling filters. If you wish to improve image quality at the expense of performance, you may wish to experiment with the alternative filters.
## Image Processing Examples
_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
{{< imgproc sunset Resize "300x" />}}
{{< imgproc sunset Fill "90x120 left" />}}
{{< imgproc sunset Fill "90x120 right" />}}
{{< imgproc sunset Fit "90x90" />}}
{{< imgproc sunset Crop "250x250 center" />}}
{{< imgproc sunset Resize "300x q10" />}}
This is the shortcode used to generate the examples above:
{{< code file="layouts/shortcodes/imgproc.html" >}}
{{< readfile file="layouts/shortcodes/imgproc.html" >}}
{{< /code >}}
Call the shortcode from your markdown like this:
```go-html-template
{{* imgproc sunset Resize "300x" /*/>}}
```
{{% note %}}
Note the self-closing shortcode syntax above. You may call the `imgproc` shortcode with or without **inner content**.
{{% /note %}}
## Imaging Configuration
### Processing Options
Define an `imaging` section in your site configuration to set the default [image processing options](#image-processing-options).
{{< code-toggle file="config" copy=true >}}
[imaging]
resampleFilter = "Box"
quality = 75
hint = "photo"
anchor = "Smart"
bgColor = "#ffffff"
{{< /code-toggle >}}
anchor
: See image processing options: [anchor](#anchor).
bgColor
: See image processing options: [background color](#background-color).
hint
: See image processing options: [hint](#hint).
quality
: See image processing options: [quality](#quality).
resampleFilter
: See image processing options: [resampling filter](#resampling-filter).
### Exif Data
Define an `imaging.exif` section in your site configuration to control the availability of Exif data.
{{< code-toggle file="config" copy=true >}}
[imaging.exif]
includeFields = ""
excludeFields = ""
disableDate = false
disableLatLong = false
{{< /code-toggle >}}
disableDate
: Hugo extracts the image creation date/time into `.Date`. Set this to `true` to disable. Default is `false`.
disableLatLong
: Hugo extracts the GPS latitude and longitude into `.Lat` and `.Long`. Set this to `true` to disable. Default is `false`.
excludeFields
: Regular expression matching the Exif tags to exclude from the `.Tags` collection. Default is `""`.
includeFields
: Regular expression matching the Exif tags to include in the `.Tags` collection. Default is `""`. To include all available tags, set this value to `".*"`.
{{% note %}}
To improve performance and decrease cache size, if you set neither `excludeFields` nor `includeFields`, Hugo excludes the following tags: `ColorSpace`, `Contrast`, `Exif`, `Exposure[M|P|B]`, `Flash`, `GPS`, `JPEG`, `Metering`, `Resolution`, `Saturation`, `Sensing`, `Sharp`, and `WhiteBalance`.
{{% /note %}}
## Smart Cropping of Images
By default, Hugo uses the [Smartcrop] library when cropping images with the `Crop` or`Fill` methods. You can set the anchor point manually, but in most cases the `Smart` option will make a good choice.
Examples using the sunset image from above:
{{< imgproc sunset Fill "200x200 smart" />}}
{{< imgproc sunset Crop "200x200 smart" />}}
## Image Processing Performance Consideration
Hugo caches processed images in the `resources` directory. If you include this directory in source control, Hugo will not have to regenerate the images in a CI/CD workflow (e.g., GitHub Pages, GitLab Pages, Netlify, etc.). This results in faster builds.
If you change image processing methods or options, or if you rename or remove images, the `resources` directory will contain unused images. To remove the unused images, perform garbage collection with:
```bash
hugo --gc
```
[`anchor`]: {{< relref "content-management/image-processing#anchor" >}}
[`lang.FormatNumber`]: {{< relref "functions/lang#langformatnumber" >}}
[Exif]:
[filters]: {{< relref "functions/images" >}}
[github.com/disintegration/imaging]:
[mounted]: {{< relref "hugo-modules/configuration#module-config-mounts">}}
[page bundle]: {{< relref "content-management/page-bundles" >}}
[Smartcrop]:
[time.Format]: {{< relref "functions/dateformat" >}}