乐趣区

关于java:关于图片压缩的一些调查

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

退出移动版