菜单

图像处理

相关源文件

本文档介绍了 Hugo 的图片处理系统,该系统提供了强大的功能,用于转换和优化 Hugo 网站中的图片。该系统支持调整大小、裁剪、旋转和格式转换等操作,以及提取图片元数据。

Hugo 图片处理系统概述

Hugo 的图片处理系统通过基于资源的 API 来转换您网站中使用的图片。图片可以作为页面资源(与内容捆绑在一起)、全局资源(存储在 assets 目录中)或远程资源(从 URL 获取)进行访问。一旦访问,这些图片就可以通过多种方法进行转换,并将结果缓存以提高性能。

来源: resources/image.go56-72 resources/resource_factories/create/create.go92-122 resources/image_cache.go28-35

资源类型和访问方法

在 Hugo 中,图片被视为资源,可以通过三种不同的方式访问

页面资源

页面资源是捆绑在页面包中与内容页面一起使用的图片

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

在模板中访问

全局资源

全局资源是存储在 assets 目录中的图片

assets/
└── images/
    └── sunset.jpg    <-- global resource

在模板中访问

远程资源

远程资源是从外部 URL 获取的图片

在模板中访问

来源: resources/resource_factories/create/create.go103-151 tpl/resources/resources.go92-151

图片处理系统的核心组件

来源: resources/image.go56-72 resources/images/image.go44-64 resources/image_cache.go28-35 resources/images/image.go198-201

图片处理方法

Hugo 提供了几种转换图片的方法。每种方法都会返回一个新的 ImageResource,可以进一步处理或渲染

进程

Process 方法是最通用的,允许使用单个字符串规范执行任何支持的操作。它是在 Hugo 0.119.0 版本中引入的,可以执行调整大小、裁剪、格式转换等操作。

调整大小 (Resize)

将图片调整到指定的尺寸,如果设置一个维度为 0,则会保留纵横比。

示例: {{ $resized := $image.Resize "300x200" }}

裁剪 (Crop)

使用锚点将图片裁剪到指定的尺寸。

示例: {{ $cropped := $image.Crop "300x200 TopLeft" }}

填充 (Fill)

缩放并裁剪图片以精确填充指定的尺寸。

示例: {{ $filled := $image.Fill "300x200 Center" }}

适应 (Fit)

缩放图片以适应指定的尺寸。

示例: {{ $fitted := $image.Fit "300x200" }}

过滤器

应用一个或多个图片滤镜。

其他方法

  • Colors():返回图片中的主色调
  • Exif():从图片中返回 EXIF 元数据

来源: resources/image.go207-326 resources/images/image.go256-274

图像处理流程

下图说明了图片在内部的处理流程

来源: resources/image_cache.go36-113 resources/image.go327-401

图片缓存架构

Hugo 采用了复杂的双层缓存系统来处理图片

缓存系统使用

  1. 内存缓存:用于快速访问频繁使用的已处理图片的内存缓存
  2. 文件缓存:持久化的缓存,存储在文件系统中,通常位于 resources/_gen/images/ 目录下

缓存键由以下因素决定

  • 原始图片内容的哈希值
  • 处理选项(例如,尺寸、格式)
  • 图片处理配置

该缓存系统通过避免对相同图片进行相同的转换处理,显著提高了性能。

来源: resources/image_cache.go36-125 resources/resource_cache.go31-81

支持的图片格式

Hugo 支持以下图片格式

格式导入导出注释
JPEG默认质量:75
PNG
GIF支持动态 GIF
TIFF
BMP
WebP
SVGSVG 可以使用但不能进行转换

可以使用 `Process` 方法或在其他转换方法中添加格式名称来执行格式转换

来源: resources/images/config.go49-70 resources/images/image.go66-115

EXIF 元数据处理

Hugo 可以使用 `Exif()` 方法从图片中提取 EXIF 元数据,该方法返回一个 `ExifInfo` 对象,其中包含以下详细信息:

  • 拍摄照片的日期和时间
  • GPS 坐标(纬度和经度)
  • 相机和镜头信息
  • 曝光和光圈设置

模板中的示例用法

EXIF 元数据在图片转换过程中不会保留,但可以从原始图片中访问。

来源: resources/image.go74-143 resources/image_test.go417-448

资源转换流程

资源转换系统是通用的,不仅用于图片,也用于所有资源类型。对于图片,特定的转换方法(Resize、Crop 等)会创建专门的 `ResourceTransformation` 对象,然后通过该管道进行处理。

来源: resources/transform.go94-146 resources/transform.go353-370

常见使用模式

以下是在模板中使用 Hugo 的图片处理功能的一些常见方法

基本图片显示与响应式尺寸调整

图片格式转换

使用图片元数据

来源: hugolib/resource_chain_test.go61-71 resources/image_test.go73-158 docs/content/en/content-management/image-processing/index.md43-69

性能考量

Hugo 的图片处理包含多项优化以最大化性能。

  1. 并发处理限制:图片处理是 CPU 和内存密集型操作,因此 Hugo 会限制并发图片处理,以避免系统过载,尤其是在生产环境中。

  2. 两级缓存:内存和文件缓存可显著减少之前处理过的图片的处理时间。

  3. 延迟发布:资源仅在其永久链接被访问时才发布(写入磁盘),避免了不必要的文件操作。

  4. 文件内容哈希:Hugo 使用内容哈希来确定图片何时发生更改以及需要重新处理。

来源: resources/image.go333-336 resources/transform.go77-93 resources/image_cache.go98-101

内部实现细节

对于有兴趣了解或扩展 Hugo 图片处理功能的开发者而言,

  1. resources/image.go 中的 imageResource 类型实现了 images.ImageResource 接口,并提供了核心的图片处理方法。

  2. 图片处理使用了 Go image packageGIFT 库进行转换。

  3. 缓存系统实现在 resources/image_cache.go 中,并结合了内存和文件缓存。

  4. EXIF 元数据提取由内部的 exif 包提供。

  5. 转换系统是 Hugo 更大的资源转换管道的一部分,允许转换链式操作。

  6. 图片处理操作使用信号量进行序列化,以防止在处理大型图片时耗尽内存。

来源: resources/image.go333-336 resources/images/image.go198-327 resources/transform.go217-258