本文档介绍了 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 版本中引入的,可以执行调整大小、裁剪、格式转换等操作。
将图片调整到指定的尺寸,如果设置一个维度为 0,则会保留纵横比。
示例: {{ $resized := $image.Resize "300x200" }}
使用锚点将图片裁剪到指定的尺寸。
示例: {{ $cropped := $image.Crop "300x200 TopLeft" }}
缩放并裁剪图片以精确填充指定的尺寸。
示例: {{ $filled := $image.Fill "300x200 Center" }}
缩放图片以适应指定的尺寸。
示例: {{ $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 采用了复杂的双层缓存系统来处理图片
缓存系统使用
resources/_gen/images/ 目录下缓存键由以下因素决定
该缓存系统通过避免对相同图片进行相同的转换处理,显著提高了性能。
来源: resources/image_cache.go36-125 resources/resource_cache.go31-81
Hugo 支持以下图片格式
| 格式 | 导入 | 导出 | 注释 |
|---|---|---|---|
| JPEG | ✓ | ✓ | 默认质量:75 |
| PNG | ✓ | ✓ | |
| GIF | ✓ | ✓ | 支持动态 GIF |
| TIFF | ✓ | ✓ | |
| BMP | ✓ | ✓ | |
| WebP | ✓ | ✓ | |
| SVG | ✓ | ✗ | SVG 可以使用但不能进行转换 |
可以使用 `Process` 方法或在其他转换方法中添加格式名称来执行格式转换
来源: resources/images/config.go49-70 resources/images/image.go66-115
Hugo 可以使用 `Exif()` 方法从图片中提取 EXIF 元数据,该方法返回一个 `ExifInfo` 对象,其中包含以下详细信息:
模板中的示例用法
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 的图片处理包含多项优化以最大化性能。
并发处理限制:图片处理是 CPU 和内存密集型操作,因此 Hugo 会限制并发图片处理,以避免系统过载,尤其是在生产环境中。
两级缓存:内存和文件缓存可显著减少之前处理过的图片的处理时间。
延迟发布:资源仅在其永久链接被访问时才发布(写入磁盘),避免了不必要的文件操作。
文件内容哈希:Hugo 使用内容哈希来确定图片何时发生更改以及需要重新处理。
来源: resources/image.go333-336 resources/transform.go77-93 resources/image_cache.go98-101
对于有兴趣了解或扩展 Hugo 图片处理功能的开发者而言,
resources/image.go 中的 imageResource 类型实现了 images.ImageResource 接口,并提供了核心的图片处理方法。
图片处理使用了 Go image package 和 GIFT 库进行转换。
缓存系统实现在 resources/image_cache.go 中,并结合了内存和文件缓存。
EXIF 元数据提取由内部的 exif 包提供。
转换系统是 Hugo 更大的资源转换管道的一部分,允许转换链式操作。
图片处理操作使用信号量进行序列化,以防止在处理大型图片时耗尽内存。
来源: resources/image.go333-336 resources/images/image.go198-327 resources/transform.go217-258