背景
使用MidJourney生成图片,如果在prompt上不设置特殊的指令参数,官方默认返回的图片清晰度比较高,尺寸也很大。项目中我们自己会把MidJourney生成的原图保存一份,这样就会存在一个问题,因为MidJourney分辨率很高,占用的空间也很大,物理存储的问题还算容易解决,但是直接在页面显示原图就会非常慢,经常会超时,一个页面动则就几十M,所以必须对图片进行缩放或者裁剪,简而简之就是需要一个缩略图。于是开始漫长的调研中…(本人主要使用Java,所以主要是调研了一些在Java中如何能直接生成一个缩略图的)
1、Thumbnailator
github地址:Thumbnailator
Thumbnailator 是一个用来生成图像缩略图的Java 类库,通过很简单的代码即可生成图片缩略图,也可直接对一整个目录的图片生成缩略图。亲自试了下,对PNG和JPEG支持的都挺好,也可以对图片进行等比例压缩。但是MidJourney的图片会有WebP格式的,Thumbnailator并不支持,代码中使用对WebP格式的图片进行压缩直接会报格式不兼容,所以,这个工具暂时用不了,期盼这个工具的作者能在哪个版本支持下,坐等。(代码就不贴出来了,搜一搜一大堆)
2、Webp-Imageio
github地址:Webp-Imageio
webp-imageio是一个Java中的图像I/O扩展库,用于支持WebP图像格式的读取和写入。它是基于Java Image I/O API的一个插件,允许Java应用程序通过标准的ImageIO类库来处理WebP格式的图像。这个工具不但可以操作WebP格式的图像,也能进行有损和无损的压缩。我本以为找到了救星,结果用的时候发现,这个工具不能对图片进行等比例压缩,只能设置一些压缩参数使图片变得清晰度比较低,并且图片也没有那么大了。如果想要保持原图大小,也可以用这个来做缩略图,缺点就是我必须自己在保存一份缩略图,以下是简单的使用示例
<dependency>
<groupId>org.sejda.imageio</groupId>
<artifactId>webp-imageio</artifactId>
<version>0.1.6</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
public static void writeImgToFile(BufferedImage image, String targetPath) throws IOException {
// 获取一个WebP ImageWriter实例
ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
// 设置输出流
try (FileOutputStream output = new FileOutputStream(targetPath);
ImageOutputStream ios = ImageIO.createImageOutputStream(output)) {
writer.setOutput(ios);
WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
// 压缩模式
writeParam.setCompressionMode(WebPWriteParam.MODE_EXPLICIT);
// 有损压缩
writeParam.setCompressionType("Lossy");
// 压缩质量,取值0~1,越小压缩率越高
writeParam.setCompressionQuality(0);
// 压缩方法
writeParam.setMethod(6);
// 写入图片
writer.write(null, new IIOImage(image, null, null), writeParam);
}
// 释放资源
writer.dispose();
}
public static void main(String[] args) {
try {
File file = FileUtil.file("C:\\Users\\Administrator\\Desktop\\test\\test.webp");
writeImgToFile(ImgUtil.read(file), "C:\\Users\\Administrator\\Desktop\\test\\test.webp");
} catch (Exception e) {
}
}
效果展示:
备注:WebPWriteParam里边有很多参数,大家不懂得可以使用GPT帮忙给解释下参数都是什么意思,现在GPT这么强大,分分钟告诉你怎么用,有需要的朋友戳链接体验:Talk-bot,不喜勿喷,广交益友
3、nginx_http_image_filter_module
nginx_http_image_filter_module是Nginx HTTP模块之一,用于实时处理图像文件,提供缩放、裁剪、旋转、格式转换等功能。需要注意的是,此模块是在Nginx 0.7.54开始引入的,对WebP格式的支持是在nginx 1.11.6版本,所以要使用Nginx操作WebP图像格式,Nginx版本需要大于等于1.11.6(Nginx版本变化可以看这里:Nginx版本变化说明),而且不用我自己在保存一份,实时生成的。功夫不负有心人,调研几天,总算有个能满足需求的,哈哈,开整:
我选用的是Nginx1.24.0版本,只要大于等于1.11.6版本即可。因为之前没用过image_filter这个玩意,不知道怎么在Nginx上安装使用,百度上一搜,说是要使用image_filter模块需要手动编译安装并指定需要的模块,妈蛋,都2023年了,还让我手动编译安装,我用下就这么费劲吗。后来我去官网看了下,nginx默认已经支持了image_filter模块(低版本的不太清楚,高版本的已经给编译好了),只需要在nginx.conf文件中导入即可,类似Java中的import
load_module /etc/nginx/modules/ngx_http_image_filter_module.so;
image_filter_module主要有以下几个指令
image_filter rotate 90 | 180 | 270 #旋转图片 image_filter resize width height #等比例缩放图片 image_filter crop width height #裁剪图片到指定大小 image_filter_buffer size #单图片缓存大小,超过该大小返回415 image_filter_interlace on #控制是否启用隔行扫描其他参数也不废话了,推荐用GPT搜下,解释的比搜索引擎上详细多了
在这给大家一个具体的使用案例,需求:通过在请求的URL路径上加width和height参数就可以动态调整图片大小,比如:原始图片url为:https://www.test.com/attachments/test.png,在请求参数中添加width和height后:https://www.test.com/attachments/test.png?width=200&height=200,再次访问,图片就变为200*200的图片尺寸了,而且图片质量也没有变化,nginx具体配置如下所示
location /attachments/ {
set $width -;
set $height -;
if ($arg_width != "") {
set $width $arg_width;
}
if ($arg_height != "") {
set $height $arg_height;
}
image_filter resize $width $height;
image_filter_buffer 10m;
image_filter_interlace on;
proxy_pass http://minio:9000;
}
效果展示: