欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java调用shell脚本执行imagemagick压缩图片

程序员文章站 2022-09-14 09:03:09
文章目录前言安装方式一:Dockerfile方式二:进入已有容器内部安装测试Linux上压缩Java执行shell实现压缩前言自己做个小项目,有个需求得存储图片,为了页面渲染速度。这里存储的是压缩图片,然后外链指向原图。本地不存储。美滋滋。但是想法很美好,结果缺不尽人意…业务逻辑上一点问题没有,结果出在服务器上,内存不足,导致宕机。一通排查之后发现是压缩图片这里导致的内存溢出。尝试解决办法:所有IO流操作完立马close,无效数量降低为每分钟处理3张图片,无效采用谷歌的开源工具th....


前言

自己做个小项目,有个需求得存储图片,为了页面渲染速度。
这里存储的是压缩图片,然后外链指向原图。本地不存储。美滋滋。
但是想法很美好,结果缺不尽人意…

业务逻辑上一点问题没有,结果出在服务器上,内存不足,导致宕机。
一通排查之后发现是压缩图片这里导致的内存溢出。
尝试解决办法:

  • 所有IO流操作完立马close,无效
  • 数量降低为每分钟处理3张图片,无效
  • 采用谷歌的开源工具thumbnailator,无效

最后无奈在linux上安装imagemagick,然后java执行shell语句去压缩图片。
然后就一路顺畅了,不得不说java的IO真的吃内存。


安装

介绍一下本文的环境,java项目运行在docker容器中,基于java:8-alpine镜像。
注意是alpine,超苗条的linux。所以很多基本指令在容器内都没有。

方式一:Dockerfile

全写注释了,就不做过多额外的解释了

FROM java:8-alpine
ADD target/xxx.jar xxx.jar
# 修改alpine的源地址改为阿里的,否则下载速度极慢
RUN echo -e "https://mirrors.aliyun.com/alpine/v3.7/main" > /etc/apk/repositories
# 更新本地apk的镜像索引数据 并且 安装imagemagick
RUN apk update && apk add imagemagick
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/xxx.jar"]

方式二:进入已有容器内部安装

# 进入容器,因为是基于alpine,所以这里用sh,而不是bash
docker exec -it xxx sh
# 修改alpine的源地址改为阿里的,否则下载速度极慢
echo -e "https://mirrors.aliyun.com/alpine/v3.7/main" > /etc/apk/repositories
# 更新本地apk的镜像索引数据 并且 安装imagemagick
apk update && apk add imagemagick

测试

convert -version

/ # convert -version
Version: ImageMagick 7.0.7-11 Q16 x86_64 2017-11-15 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP
Delegates (built-in): bzlib cairo fontconfig freetype gslib jng jpeg lcms ltdl pangocairo png ps rsvg tiff webp xml zlib
/ #


Linux上压缩

官方示例:https://www.imagemagick.org/Usage/

# 压缩质量为70% 1.png:源文件 to1.jpng:压缩后的文件 
convert -quality 70% 1.png to1.jpg && rm -f 1.png
# 如何用这个还是提示内存不足的话,再加上两个参数即可。设置最大内存2mb
convert -limit memory 2mb -limit map 2mb -quality 70% 1.png to1.jpg && rm -f 1.png


Java执行shell实现压缩

String cmd = "convert -limit memory 2mb -limit map 2mb -quality 70% 1.png to1.jpg && rm -f 1.png";
// "sh", "-c"不可省略,waitFor:阻塞线程等待shell执行结束
Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd}).waitFor();

本文地址:https://blog.csdn.net/wkh___/article/details/107144869