图像处理

Image Processing - 图像处理

https://gohugo.io/content-management/image-processing/

​ 调整大小、裁剪、旋转、滤镜和转换图像。

图像资源

​ 要处理图像,必须将其作为页面资源或全局资源访问。

页面资源

​ 页面资源是page bundle中的文件。page bundle是一个在其根目录下具有index.md_index.md文件的目录。

1
2
3
4
5
content/
└── posts/
    └── post-1/           <-- page bundle
        ├── index.md
        └── sunset.jpg    <-- page resource

全局资源

​ 全局资源是一个文件:

  • assets目录中,或
  • 在任何已挂载assets目录的目录中,或
  • 位于通过httphttps可访问的远程服务器上
1
2
3
assets/
└── images/
    └── sunset.jpg    <-- global resource

​ 要访问本地图像作为全局资源:

1
{{ $image := resources.Get "images/sunset.jpg" }}

​ 要将远程图像作为全局资源访问:

1
{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}

图像渲染

​ 一旦您已经将图像作为页面资源或全局资源之一访问,可以使用PermalinkRelPermalinkWidthHeight属性在模板中呈现它。

示例1:如果未找到资源,则会引发错误。

1
2
{{ $image := .Resources.GetMatch "sunset.jpg" }}
<img src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}">

示例2:如果未找到资源,则跳过图像渲染。

1
2
3
4
{{ $image := .Resources.GetMatch "sunset.jpg" }}
{{ with $image }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}

示例3:如果未找到资源,则跳过图像渲染的更简洁的方法。

1
2
3
{{ with .Resources.GetMatch "sunset.jpg" }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}

图像处理方法

image资源实现了ResizeFitFillCropFilterColorsExif方法。

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.

​ 在图像转换期间,元数据(Exif,IPTC,XMP等)不会被保留。请使用[Exif]方法和原始图像从JPEG或TIFF图像中提取Exif元数据。

Resize

​ 将图像调整为指定的宽度和/或高度。

​ 如果同时指定宽度和高度,则结果图像将不成比例缩放,除非原始图像具有相同的宽高比。

1
2
3
4
5
6
7
8
{{/* 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

​ 按比例缩小图像以适应给定的尺寸。您必须同时提供宽度和高度。

1
{{ $image := $image.Fit "600x400" }}

Fill

​ 裁剪并调整图像以匹配给定的尺寸。您必须同时提供宽度和高度。使用 anchor 选项可以更改裁剪框锚点。

1
{{ $image := $image.Fill "600x400" }}

Crop

​ 裁剪图像以匹配给定的尺寸而不调整大小。您必须同时提供宽度和高度。使用 anchor 选项可以更改裁剪框锚点。

1
{{ $image := $image.Crop "600x400" }}

Filter

​ 对图像应用一个或多个滤镜

1
{{ $image := $image.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}

​ 使用管道以更函数式的风格编写此内容。 Hugo按照给定的顺序应用过滤器。

1
{{ $image := $image | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }}

​ 有时候创建一个过滤器链并重复使用它是很有用的。

1
2
3
{{ $filters := slice  (images.GaussianBlur 6) (images.Pixelate 8) }}
{{ $image1 := $image1.Filter $filters }}
{{ $image2 := $image2.Filter $filters }}

Colors

New in v0.104.0

.Colors 方法使用简单的直方图方法返回图像中的主要颜色的十六进制字符串切片。

1
{{ $colors := $image.Colors }}

​ 此方法速度很快,但如果您还缩小图像,从缩小的图像提取颜色可提高性能。

Exif

​ 提供一个包含图像元数据的 Exif 对象。

​ 您可以访问 JPEG 和 TIFF 图像中的 Exif 数据。为避免处理没有 Exif 数据的图像时出现错误,请将访问包装在 with 语句中。

1
2
3
4
5
6
7
8
{{ with $image.Exif }}
  Date: {{ .Date }}
  Lat/Long: {{ .Lat }}/{{ .Long }}
  Tags:
  {{ range $k, $v := .Tags }}
    TAG: {{ $k }}: {{ $v }}
  {{ end }}
{{ end }}

​ 您还可以使用lang.FormatNumber函数单独访问Exif字段,根据需要格式化字段。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ with $image.Exif }}
  <ul>
    {{ with .Date }}<li>Date: {{ .Format "January 02, 2006" }}</li>{{ end }}
    {{ with .Tags.ApertureValue }}<li>Aperture: {{ lang.FormatNumber 2 . }}</li>{{ end }}
    {{ with .Tags.BrightnessValue }}<li>Brightness: {{ lang.FormatNumber 2 . }}</li>{{ end }}
    {{ with .Tags.ExposureTime }}<li>Exposure Time: {{ . }}</li>{{ end }}
    {{ with .Tags.FNumber }}<li>F Number: {{ . }}</li>{{ end }}
    {{ with .Tags.FocalLength }}<li>Focal Length: {{ . }}</li>{{ end }}
    {{ with .Tags.ISOSpeedRatings }}<li>ISO Speed Ratings: {{ . }}</li>{{ end }}
    {{ with .Tags.LensModel }}<li>Lens Model: {{ . }}</li>{{ end }}
  </ul>
{{ end }}

Exif变量

  • .Date

    图像创建日期/时间。使用time.Format函数格式化。

  • .Lat

    GPS纬度(latitude 以度为单位)。

  • .Long

    GPS经度(longitude 以度为单位)。

  • .Tags

    此图像可用的Exif标签集合。您可以在站点配置中包含或排除特定标签。

图像处理选项

ResizeFitFillCrop方法接受一个以空格分隔、大小写不敏感的选项列表。列表中的选项顺序无关紧要。

尺寸

​ 使用Resize方法,必须指定宽度、高度或两者。FitFillCrop方法需要宽度和高度。所有尺寸以像素为单位。

1
2
3
4
5
6
{{ $image := $image.Resize "600x" }}
{{ $image := $image.Resize "x400" }}
{{ $image := $image.Resize "600x400" }}
{{ $image := $image.Fit "600x400" }}
{{ $image := $image.Fill "600x400" }}
{{ $image := $image.Crop "600x400" }}

旋转

​ 将图像逆时针旋转给定角度。 Hugo在缩放之前执行旋转。例如,如果原始图像为600x400,并且您希望将图像逆时针旋转90度,并将其缩小50%:

1
{{ $image = $image.Resize "200x r90" }}

​ 在上面的示例中,宽度表示旋转后的期望宽度。

​ 要在不缩放的情况下旋转图像,请使用原始图像的尺寸:

1
2
3
4
5
{{ with .Resources.GetMatch "sunset.jpg" }}
  {{ with .Resize (printf "%dx%d r90" .Height .Width) }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
  {{ end }}
{{ end }}

​ 在上面的示例中,第二行我们反转了宽度和高度,以反映旋转后期望尺寸。

锚点

​ 使用CropFill方法时,锚点确定裁剪框的放置位置。您可以指定TopLeftTopTopRightLeftCenterRightBottomLeftBottomBottomRightSmart

​ 默认值为Smart,它使用Smartcrop图像分析来确定裁剪框的最佳放置位置。您可以在站点配置中覆盖默认值。

​ 例如,如果您有一个400x200像素的图像,其中鸟位于左上象限,您可以创建一个包含鸟的200x100缩略图:

1
{{ $image.Crop "200x100 TopLeft" }}

​ 如果在使用CropFill方法时应用旋转,则相对于旋转后的图像指定锚点。

目标格式

​ 默认情况下,Hugo将图像编码为源格式。您可以通过指定bmpgifjpegjpgpngtiftiffwebp将图像转换为另一种格式。

1
{{ $image.Resize "600x webp" }}

​ 使用原始图像的尺寸而不缩放来转换图像:

1
2
3
4
5
{{ with .Resources.GetMatch "sunset.jpg" }}
  {{ with .Resize (printf "%dx%d webp" .Width .Height) }}
    <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
  {{ end }}
{{ end }}

质量

​ 适用于JPEG和WebP图像,q值确定转换图像的质量。更高的值会产生更好的质量图像,而更低的值会产生更小的文件。将此值设置为介于1和100之间(包括1和100)的整数。

​ 默认值为75。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x webp q50" }}

提示

​ 适用于WebP图像,此选项对应于一组预定义的编码参数。

ValueExample
drawing高对比度手绘或线描图像
icon小型彩色图像
photo自然光照的户外照片
picture室内照片,例如肖像
text主要是文本的图像

​ 默认值为photo。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x webp picture" }}

背景色

​ 当将支持透明度的图像(例如PNG)转换为不支持透明度的图像(例如JPEG)时,可以指定结果图像的背景颜色。

​ 使用3位或6位十六进制颜色代码(例如#00f#0000ff)。

​ 默认值为#ffffff(白色)。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x jpg #b31280" }}

重采样滤镜

You may specify the resampling filter used when resizing an image. Commonly used resampling filters include:

您可以在调整图像大小时指定使用的重采样滤镜。常用的重采样滤镜包括:

调整图像大小时,可以指定所使用的重采样滤镜。常用的重采样滤镜包括:

FilterDescription
Box适合缩小的简单快速平均滤镜
Lanczos用于摄影图像的高质量重采样滤镜,产生锐利的结果
CatmullRom尖锐的立方滤镜,比Lanczos滤镜快,提供类似的结果
MitchellNetravali立方体滤镜,产生比 CatmullRom 更平滑的结果,减少了环状伪影
Linear双线性重采样滤镜,产生平滑的输出,比立方体滤镜更快
NearestNeighbor最快的重采样滤镜,无抗锯齿

​ 默认值为 Box。您可以在站点配置中覆盖默认值。

1
{{ $image.Resize "600x400 Lanczos" }}

​ 请参见github.com/disintegration/imaging以获取完整的重采样滤镜列表。如果您希望以性能为代价改善图像质量,可以尝试使用替代滤镜。

图像处理示例

​ 以下示例中使用的日落照片版权归Bjørn Erik Pedersen所有(Creative Commons Attribution-Share Alike 4.0 International license)。

image-20230423173937490

​ 这是用于生成上述示例的shortcode :

layouts/shortcodes/imgproc.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{{ $img := .Page.Resources.GetMatch (printf "*%s*" (.Get 0)) }}
{{ $command := .Get 1 }}
{{ $options := .Get 2 }}
{{ if eq $command "Fit"}}
  {{ $img = $img.Fit $options }}
{{ else if eq $command "Resize"}}
  {{ $img = $img.Resize $options }}
{{ else if eq $command "Fill"}}
  {{ $img = $img.Fill $options }}
{{ else if eq $command "Crop"}}
  {{ $img = $img.Crop $options }}
{{ else }}
  {{ errorf "Invalid image processing command: Must be one of Crop, Fit, Fill or Resize."}}
{{ end }}
<figure style="padding: 0.25rem; margin: 2rem 0; background-color: #cccc">
  <img style="max-width: 100%; width: auto; height: auto;" src="{{ $img.RelPermalink }}" width="{{ $img.Width }}" height="{{ $img.Height }}">
  <figcaption>
  <small>
    {{ with .Inner }}
      {{ . }}
    {{ else }}
      .{{ $command }} "{{ $options }}"
    {{ end }}
  </small>
  </figcaption>
</figure>

​ 在您的Markdown中像这样调用shortcode :

1
\{\{\< imgproc sunset Resize "300x" /\>\}\}

​ 注意上面自我封闭的shortcode语法。您可以使用或不使用内部内容来调用imgproc shortcode 。

图像处理配置

处理选项

​ 在您的站点配置中定义一个imaging处理部分,以设置默认的图像处理选项

config.

=== “yaml”

``` yaml
imaging:
  anchor: Smart
  bgColor: '#ffffff'
  hint: photo
  quality: 75
  resampleFilter: Box
```

=== “toml”

``` toml
[imaging]
  anchor = 'Smart'
  bgColor = '#ffffff'
  hint = 'photo'
  quality = 75
  resampleFilter = 'Box'
```

=== “json”

``` json
{
   "imaging": {
      "anchor": "Smart",
      "bgColor": "#ffffff",
      "hint": "photo",
      "quality": 75,
      "resampleFilter": "Box"
   }
}
```

Exif 数据

在您的站点配置中定义一个 imaging.exif 部分,以控制 Exif 数据的可用性。

config.

=== “yaml”

``` yaml
imaging:
  exif:
    disableDate: false
    disableLatLong: false
    excludeFields: ""
    includeFields: ""
```

=== “toml”

``` toml
[imaging]
  [imaging.exif]
    disableDate = false
    disableLatLong = false
    excludeFields = ''
    includeFields = ''
```

=== “json”

``` json
{
   "imaging": {
      "exif": {
         "disableDate": false,
         "disableLatLong": false,
         "excludeFields": "",
         "includeFields": ""
      }
   }
}
```
  • disableDate

    Hugo 将图像创建日期/时间提取到 .Date 中。将此设置为 true 以禁用。默认值为 false

  • disableLatLong

    Hugo 将 GPS 纬度和经度提取到 .Lat.Long 中。将此设置为 true 以禁用。默认值为 false

  • excludeFields

    正则表达式匹配要从 .Tags 集合中排除的 Exif 标记。默认值为 ""

  • includeFields

    正则表达式匹配要在 .Tags 集合中包含的 Exif 标记。默认值为 ""。要包括所有可用的标记,请将此值设置为 ".*"

​ 为了提高性能并减小缓存大小,如果您既不设置 excludeFields 也不设置 includeFields,则 Hugo 将排除以下标记:ColorSpaceContrastExifExposure[M|P|B]FlashGPSJPEGMeteringResolutionSaturationSensingSharpWhiteBalance

智能裁剪图像

​ 默认情况下,Hugo在使用CropFill方法裁剪图像时会使用Smartcrop库。您可以手动设置锚点,但在大多数情况下,Smart选项会做出很好的选择。

​ 以下是使用上面的日落图片的示例:

image-20230423174039092

图像处理性能考虑

​ Hugo在resources目录中缓存处理过的图像。如果您将此目录包含在源代码控制中,Hugo将不必在CI / CD工作流程(例如,GitHub Pages,GitLab Pages,Netlify等)中重新生成图像。这将加快构建速度。

​ 如果您更改图像处理方法或选项,或者重命名或删除图像,则resources目录将包含未使用的图像。要删除未使用的图像,请执行垃圾回收:

1
hugo --gc

另请参阅

最后修改 May 22, 2023: 第一次提交 (9f24e27)