GraphicsMagick之实践出真知

介绍

GraphicsMagick 是个图片处理库,是从ImageMagick 5.5.2分支出来的,但是现在他变得更稳定和更轻、更快一些

GraphicsMagick 号称图像处理领域的瑞士军刀。 短小精悍的代码却提供了一个鲁棒、高效的工具和库集合,来处理图像的读取、写入和操作,支持超过88种图像格式,包括重要的DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF。 通过使用 OpenMP 可是利用多线程进行图片处理,增强了通过扩展 CPU 提高处理能力。GraphicsMagick可以再绝大多数的平台上使用,Linux、Mac、Windows都没有问题。

GraphicsMagick 支持大图片的处理,并且已经做过GB级别的图像处理实验。GraphicsMagick 能够动态的生成图片,特别适用于互联网的应用。可以用来处理调整尺寸、旋转、加亮、颜色调整、增加特效等方面。GaphicsMagick 不仅支持命令行的模式,同时也支持C、C++、Perl、PHP、Tcl、Ruby等的调用。

安装

虽然在上篇中已经提到过如何安装 GraphicsMagick,这里还要再啰嗦一遍,因为这里有个小坑,希望对大家有所帮助。

Mac 上安装 GraphicsMagick 有两种方式,brew 命令一键式安装虽然简单,但是它默认会加一些配置信息,导致我们没法使用 GraphicsMagick 的 OpenMP 功能,所以我们最好还是手动编译安装。

brew安装

Mac 可以使用 brew 命令:

brew install libpng
brew install libjpeg
#通过 brew 安装 GraphicsMagick(libpng 等依赖包会一并下载)
brew install graphicsmagick

// 删除命令
brew uninstall graphicsmagick
brew cleanup -s

查看 GraphicsMagick 的版本以及安装路径:

% gm -version
GraphicsMagick 1.3.38 2022-03-26 Q16 http://www.GraphicsMagick.org/
......
Configured using the command:
  ./configure  '--prefix=/usr/local/Cellar/graphicsmagick/1.3.38_1' '--disable-dependency-tracking' '--disable-openmp' '--disable-static' '--enable-shared' '--with-modules' '--with-quantum-depth=16' '--without-lzma' '--without-x' '--without-gslib' '--with-gs-font-dir=/usr/local/share/ghostscript/fonts' '--without-wmf' 'CC=clang' 'CXX=clang++' 'PKG_CONFIG_PATH=/usr/local/opt/libpng/lib/pkgconfig:/usr/local/opt/freetype/lib/pkgconfig:/usr/local/opt/jpeg-turbo/lib/pkgconfig:/usr/local/opt/jasper/lib/pkgconfig:/usr/local/opt/libtiff/lib/pkgconfig:/usr/local/opt/little-cms2/lib/pkgconfig:/usr/local/opt/webp/lib/pkgconfig' 'PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig:/usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig/11'
.....

由上可知,brew 命令默认执行 ./configure 命令时,包含了“--disable-openmp”指令,该指令意味着完全禁用 OpenMP(自动多线程循环),会降低 GraphicsMagick 处理图片的性能。关于这点会在下文详细介绍。

手动编译安装

mkdir /usr/local/tools

tar -xvf GraphicsMagick-1.3.37.tar.gz -C /hresh/tool/

# 进入GraphicsMagick安装目录
./configure --prefix=/hresh/tool/GraphicsMagick-1.3.37 --enable-shared --enable-openmp-slow

make && make install

在 .bash_profile 文件中设置环境变量:

export GMAGICK_HOME="/hresh/tool/GraphicsMagick-1.3.37"
export PATH="$GMAGICK_HOME/bin:$PATH"
export LD_LIBRARY_PATH="$GMAGICK_HOME/lib/"
export OMP_NUM_THREADS=6

OMP_NUM_THREADS 环境变量,表示GM可使用的线程数。必须设置OMP_NUM_THREADS 环境变量才可以真正使用起多线程(openmp)。

查看 GraphicsMagick 的版本以及安装路径:

% gm -version           
GraphicsMagick 1.3.37 20201226 Q16 http://www.GraphicsMagick.org/

Configured using the command:
  ./configure  '--prefix=/hresh/tool/GraphicsMagick-1.3.37' '--enable-shared' '--enable-openmp-slow'

删除 GraphicsMagick

make distclean
make uninstall

OOM问题

我们在之前一篇文章中介绍过如何通过 Im4Java 给图片添加图片水印,代码如下所示:

public static void addImgWatermark(String srcImagePath, String destImagePath, String waterImgPath)
  throws Exception {
  // 原始图片信息
  BufferedImage targetImg = ImageIO.read(new File(srcImagePath));
  // 水印图片
  BufferedImage watermarkImage = ImageIO.read(new File(waterImgPath));
  int w = targetImg.getWidth();
  int h = targetImg.getHeight();
  IMOperation op = new IMOperation();
  // 水印图片位置
  op.geometry(watermarkImage.getWidth(), watermarkImage.getHeight(),
              w - watermarkImage.getWidth() - 300, h - watermarkImage.getHeight() - 100);
  // 水印透明度
  op.dissolve(90);
  // 水印
  op.addImage(waterImgPath);
  // 原图
  op.addImage(srcImagePath);
  // 目标
  op.addImage(destImagePath);
  ImageCommand cmd = getImageCommand(CommandType.imageWaterMark);
  cmd.run(op);
}

当时只考虑基本功能实现了,并未注意细节问题,经同事提醒,发现 ImageIO.read()这种方式来获取原图片的宽高信息,会将整个图片流读取到内存,浪费了大量的空间并且还增加了 OOM 风险。

通过BufferedImage获取宽高

测试代码如下:

public static void addImgWatermark(String srcImagePath, String destImagePath,
                                   String waterImgPath) {
  System.out.println(Thread.currentThread().getName() + "开始生成图片水印。。。。。。。");
  try {
   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值