JNI调用GraphicsMagick进行图片处理

最近在项目中要用到部分图片处理功能,测试了java的几个图片类库,发现性能都不够理想,听说GraphicsMagick的性能不错,打算试试;

GraphicsMagick官方提供了很多语言的接口,例如c/c++、lua、nodeJs、python,但可惜没有Java,因此可选的方案主要有以下几种:

  • JNI 实现;
  • nginx+lua实现
  • ProcessBuilder调用gm实现;
    第三种方案,由于性能问题,暂不考虑;
    第一和第三种方案都比较适合,但由于该项目主要采用java开发,因此采用了第一种方案;

JNI方案

GraphicsMagick提供了 C Core和 C Wand接口,本文以调用C Wand接口作为例子;

  1. Java接口定义native方法,并编译;
public class ImageConverter {
    public native int convert(String inFile, String outFile);
}
javac ImageConverter.java 
  1. 通过javah产生头文件;
javah -jni ImageConverter

产生的C头文件如下,的语法高亮不大会用,还是截图吧:

JNI调用GraphicsMagick进行图片处理_第1张图片
ImageConverter.h
  1. 实现C接口


    JNI调用GraphicsMagick进行图片处理_第2张图片
    ImageConverter.c
  2. 编译(linux)

gcc -fPIC -shared -I /usr/local/GraphicsMagick-1.3.23  -I /usr/local/jdk1.7.0_79/include -I /usr/local/jdk1.7.0_79/include/linux -c ImageConverter.c

gcc  -fPIC -shared -dynamiclib -o libImageConverter.so ImageConverter.o -O `GraphicsMagickWand-config --cppflags --ldflags --libs`

注意的是,在安装编译GraphicsMagick时,需要增加“enable-shared"参数
附安装脚本(支持jpeg和png,如果要支持webp请安装相应编码器):

yum install freetype gd-devel libgomp libjpeg libjpeg-devel libpng libpng-devel
./configure --enable-shared
make & make install
  1. 编译(mac)
gcc -I /usr/local/GraphicsMagick-1.3.23  -I /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/include -I /Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/include/darwin -c ImageConverter.c

gcc  -O `GraphicsMagickWand-config --cppflags --ldflags --libs` -dynamiclib -o libImageConverter.jnilib ImageConverter.o

附GraphicsMagick安装脚本:

brew install libjpeg
rew install libpng
brew install freetype
brew install jasper
./configure --enable-shared
make & make install

简单测试了下,处理1W张图片,大概耗时67320ms,cpu的load70%左右,单张图片耗时6.7ms;如果用process方式,比jni会慢5倍;不过令人例外的是测试lua方案时,发现比jni要慢不少;看了看lua的源码,要来在执行convert时,其是通过调用gm命令实现的,和process的方式类似;

其它

c/c++的编译很麻烦,可以借助maven插件来简化,有兴趣的可以参考我的github工程

你可能感兴趣的:(JNI调用GraphicsMagick进行图片处理)