最近在项目中要用到部分图片处理功能,测试了java的几个图片类库,发现性能都不够理想,听说GraphicsMagick的性能不错,打算试试;
GraphicsMagick官方提供了很多语言的接口,例如c/c++、lua、nodeJs、python,但可惜没有Java,因此可选的方案主要有以下几种:
- JNI 实现;
- nginx+lua实现
- ProcessBuilder调用gm实现;
第三种方案,由于性能问题,暂不考虑;
第一和第三种方案都比较适合,但由于该项目主要采用java开发,因此采用了第一种方案;
JNI方案
GraphicsMagick提供了 C Core和 C Wand接口,本文以调用C Wand接口作为例子;
- Java接口定义native方法,并编译;
public class ImageConverter {
public native int convert(String inFile, String outFile);
}
javac ImageConverter.java
- 通过javah产生头文件;
javah -jni ImageConverter
产生的C头文件如下,简书的语法高亮不大会用,还是截图吧:
ImageConverter.h-
实现C接口
ImageConverter.c -
编译(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
- 编译(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工程
网友评论