仍旧是 srping cloud 的我的项目,因为图片需要变大,为了节俭空间和减速加载,打算把客户上传的图片进行压缩。为了省钱,先不必 CDN,先把图片缩放大:)
1. Thumbnailator
专门用于压缩的 jar 包,很好用,只须要用引入我的项目就能够应用,反对固定大小,按比例放大等
官网给的例子参考 thumbnailator
2. ImageMagick
功能强大,不仅仅能压缩图片,还能做各种图片格式的互相转换,做各种图片特效解决,当初曾经反对比拟新的 webp 和 avif 格局。
官网 imagemagick
3. GraphicsMagick
ImageMagick 的精简版分支,更适宜用作服务器部署,im 提供的根底性能 GM 简直都反对,同样也反对 webp 格局 (avif 目前没有), 大小比 IM 小,效率感觉比 IM 高。
官网 graphicsmagick
抉择
我的我的项目始终是应用 Thumbnailator 在进行压缩,然而是在须要用到的压缩的业务所在的服务,本人引入 jar 包去实现,这样做的形式很不便,却会产生很多反复的代码,尽管压缩的局部写成了共通办法,然而依然防止不了须要反复写很多上传和下载的模板接口。所以决定将图片上传,存储,查看,下载,做成根底微服务。咱们因为用户上传图片可能是手机相机拍照的会很大,所以打算将图片压缩为 webp 格局存储。当初大部分的古代浏览器都反对 webp 格局,并且咱们是基于小程序的我的项目,所以应该是没问题的。
基于以上起因,最初我选定了用 GraphicsMagick+IM4java 来实现在 boot 上构建图片压缩服务。IM4java 是 IM 的一个 javaApi,它应用命令行模式调用 IM,当初 IM4java 也反对 GraphicsMagick,然而官网有提到,一些 GM 不反对的命令行还是用不了的,毕竟是给 IM 用的。官网 im4java 上有很多参考。
装置
Thumbnailator 是 jar 包,间接援用就能够了。
ImageMagick 当初的版本是 7,反对 CenterOs 8,基于我的环境是 CenterOs7 所以应用 6 的旧版本 ImageMagick-6.9.12
GraphicsMagick 当初的版本是 GraphicsMagick-1.3.36,我应用的是以后最新版本。
1.ImageMagick 的装置
能够下载 Rpm 包装置,不过我应用的是从源码编译,因为我的服务器版本太低,所以本人编译源码
官网提供的源码编译流程
问题:
装置实现后,应用identify -version 或者 convert -list format 查看反对的文件类型。如果没找到须要的反对类型,就须要本人去装置额定的库。如果不反对 xxx, 那么就要去装置对应的 libxxx 和 libxxx-devel 包。比方不反对 png , 就装置 libpng 和 libpng-devel 包。在装置好这些额定库之后,须要从新编译装置 IM
./configure --enable-shared #应用共享库
#生成 makefile 没问题后编译装置
make && make install
就能够了。
ps:通常如果你的 OS 版本和他的提供的版本吻合的话,是不会呈现这种问题的。最好的解决方案还是找一个吻合的版本,因为即使是本人装库,也要找对应的版本(非常坑)
2.GraphicsMagick 的装置
对于 GraphicsMagick 我要阐明一下我的版本
CentOS Linux release 7.9.2009 个别装置流程就能够应用:)
CentOS Linux release 7.4.1708 装置会有问题:(共享库装不下来,须要自定义装置共享库,而后指定共享库地位。
./configure LDFLAGS=-L/usr/local/lib (指定地位到 /usr/local/lib
-
下载 GraphicsMagick-1.3.36.tar.gz 包,放到服务器上。
# 解压 tar -xvzf GraphicsMagick-1.3.36.tar.gz #进入 GraphicsMagick cd GraphicsMagick-1.3.36
-
装置依赖库
yum install gcc gcc-c++ libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libwebp-devel libwebp
-
编译装置 指定能够解决的图像深度 32 位。应用共享库,不指定 -prefix, 则会装置在 /usr/local/bin 参考 Linux 命令详解./configure、make、make install 命令
# ./configure --with-quantum-depth=32 --enable-shared make && make install
-
应用 gm 命令,如果不可用,在 profile 中配置
vi /etc/profile export PATH=$PATH:/usr/local/bin source /etc/profile
-
关联动态链接库地址, 装置了一个新的动态链接库时, 就须要手动运行 lfconfig 命令
sudo ldconfig /usr/local/lib
装置实现后 就能够应用 convert 命令测试了。
3. IM4java 的应用
maven 引入
<dependency>
<groupId>org.im4java</groupId>
<artifactId>im4java</artifactId>
<version>1.4.0</version>
</dependency>
IM4Java 能够同时兼容 IM 和 GM
上面是 windows 的例子
public static void im(){
// 如果不配置环境变量就须要指定地位
String imPath="C:\\Program Files\\ImageMagick-6.9.12-Q16-HDRI";
ConvertCmd cmd = new ConvertCmd();
cmd.setSearchPath(imPath);
// create command;
// create the operation, add images and operators/options
IMOperation op = new IMOperation();
op.addImage("D:\\temp\\pic\\1.jpg");
op.resize(1500,3000);
op.define("webp:target-size=307200");
op.define("webp:pass=9");
op.addImage("D:\\temp\\pic\\40.webp");
try {cmd.run(op);
} catch (IOException e) {e.printStackTrace();
} catch (InterruptedException e) {e.printStackTrace();
} catch (IM4JavaException e) {e.printStackTrace();
}
}
public static void gm(){
String imPath="C:\\Program Files\\GraphicsMagick-1.3.36-Q16";
// 和 IM 的区别,须要指定是是否要封装 GM
ConvertCmd cmd = new ConvertCmd(true);
cmd.setSearchPath(imPath);
// create command;
// create the operation, add images and operators/options
IMOperation op = new IMOperation();
op.addImage("D:\\temp\\pic\\1.jpg");
op.resize(1500,3000);
op.define("webp:target-size=307200");
op.define("webp:pass=9");
op.addImage("D:\\temp\\pic\\gm40.webp");
try {cmd.run(op);
} catch (IOException e) {e.printStackTrace();
} catch (InterruptedException e) {e.printStackTrace();
} catch (IM4JavaException e) {e.printStackTrace();
}
}
LINUX 例子
public static void gm(){
//export 之后
ConvertCmd cmd = new ConvertCmd(true);
IMOperation op = new IMOperation();
op.addImage("../2M.jpg");
op.resize(1500,3000);
op.define("webp:target-size=307200");
op.define("webp:pass=9");
op.addImage("../40.webp");
try {cmd.run(op);
} catch (IOException e) {e.printStackTrace();
} catch (InterruptedException e) {e.printStackTrace();
} catch (IM4JavaException e) {e.printStackTrace();
}
}
没差,就是门路的区别而已。:)
顺带附送一下 webp 的 google 文档,对于一些参数设置有帮忙
google webp