头图

仍旧是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


kasaya
16 声望9 粉丝

SLAYERS スレイヤーズ