MinIO 自动生成缩略图的几种解决方案

MinIO 本身只负责对象存储,并不具备“根据尺寸实时生成缩略图”的内置接口。要在 MinIO 方案里“按指定尺寸拿到原图缩略图”。

一、主流做法只有两类:

1. 先算后存:上传原图时,用异步钩子把常用尺寸全部裁好,再写回 MinIO,业务端直接取对应 Object 即可;

2. 实时计算:MinIO 只存原图,读取时由外部图片服务(imgproxy、nginx-image-filter、自研 Gateway 等)即时裁剪并缓存。

MinIO 自动生成缩略图的几种解决方案

二、下面给出可直接落地的 3 种方案与示例代码

方案 1:minio-plus(Spring Boot Starter,最省事)

GitHub 项目 minio-plus 在原上传接口里做了 AOP:

  • 上传原图 → 自动生成宽度 300 px 等比缩略图 → 分别落入 {bucket}/image(原图)与 {bucket}/image-preview(缩略图)两个目录,ObjectName 一样。
  • 业务端直接拿 preview 桶地址即可,支持预签名 URL。

具体使用用法

1.1 引入依赖(已推 Maven Central)

<dependency>
  <groupId>com.github.ixleo</groupId>
  <artifactId>minio-plus-spring-boot-starter</artifactId>
  <version>2.2.0</version>
</dependency>

1.2 配置文件

minio:
  endpoint: http://minio:9000
  access-key: minioadmin
  secret-key: minioadmin
  plus:
    thumbnail-width: 300          # 默认缩略图宽
    thumbnail-bucket: ${bucket}-preview

1.3 上传文件

String originUrl  = minioPlusTemplate.putObject("product", file);
String thumbUrl   = minioPlusTemplate.getPreviewUrl("product", fileName);
// thumbUrl 已经是 300w 的缩略图,带签名

如需要其它尺寸,可再调用 `generatePreview(“product”, fileName, 800)` 动态生成并缓存 。

MinIO 自动生成缩略图的几种解决方案

方案2:imgproxy 实时裁剪 + MinIO 后端(最通用)

imgproxy 是 Go 写的单一镜像,支持 “S3-Compatible” 源,可把 MinIO 当成原图后端,通过 URL 参数实时返回任意尺寸、格式、质量的图片,且自带内存缓存 / S3-Cache。

docker-compose 最小集

services:
  minio:
    image: minio/minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
  imgproxy:
    image: darthsim/imgproxy:latest
    environment:
      IMGPROXY_USE_S3: true
      IMGPROXY_S3_ENDPOINT: http://minio:9000
      AWS_ACCESS_KEY_ID: minioadmin
      AWS_SECRET_ACCESS_KEY: minioadmin
    ports:
      - "8080:8080"

原图已放入 `images/202409/cat.jpg`,需要 200×200 居中裁剪、webp 格式、80% 质量:

http://localhost:8080/insecure/w:200/h:200/gravity:sm/quality:80/plain/local

参数解释

  • `local://` 代表走 S3-Compatible(即 MinIO)
  • 宽 `w:200`、高 `h:200`、重心 `gravity:sm`、质量 `quality:80`

imgproxy 会先从 MinIO 拉原图 → 计算 → 返回 WebP,同时把结果写进本地内存 / S3-Cache,下次同一尺寸直接命中,不再计算 。

MinIO 自动生成缩略图的几种解决方案

方案 3:自研“缩略图网关”+MinIO 事件通知(最灵活)

如果公司对尺寸、水印、格式有极多不定规则,可把“缩略图服务”做成独立微服务,通过 MinIO 事件通知(kafka/nats/webhook)异步生成。

3.1 配置事件

在 MinIO 控制台给 `images` 桶新增事件:

“PUT/POST 结束时触发 → 推送到 kafka topic: generate-thumb”。

3.2 缩略图服务消费消息

@KafkaListener(topics = "generate-thumb")
public void handle(MinioEvent event) {
String bucket = event.getBucket();
String obj    = event.getObject();
// 1. 从 minio 拉原图
InputStream origin = minioClient.getObject(bucket, obj);
// 2. 用 Thumbnailator 按规则裁多套尺寸
Thumbnails.of(origin)
.size(300, 300)
.keepAspectRatio(true)
.outputFormat("jpg")
.toFile("/tmp/thumb_300.jpg");
// 3. 写回 MinIO
minioClient.putObject("thumb-300", obj, "/tmp/thumb_300.jpg");
}

3.3 业务端

需要 300 像素图时直接访问

`http://minio:9000/thumb-300/{obj}?X-Amz-Signature=…`

若尺寸不存在,可回退到 302 到 imgproxy 实时裁一张并异步写回,实现“懒生成” 。

三、总结

  • MinIO 只存不裁;
  • 想要“按尺寸拿缩略图”,要么“先算后存”(minio-plus、自研异步),要么“实时算”(imgproxy、nginx-image-filter)。
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 共1条

请登录后发表评论