This is a Java wrapper which binds some operations from libvips using JNI.
This project is deployed and used in production for applying image transformations in the Criteo internal CDN.
Available operations:
- Resize
- Pad
- Crop
- Find trim (get bounding box)
- Get pixel point
- Get image width / height / bands / Nb frame
- Has alpha channel
- Is sRGB colorspace
- Compose image with another one
Not all libvips capabilities are implemented. Feel free to add them.
JVips build some dependencies from source in order to maximize optimizations. Linux libraries are embedded in jar file.
Libraries are downloaded from given url in lib/build.sh. Edit lib/variable.sh for updating libraries version.
Make sure you have cmake3 installed and every dependencies required by libvips on your system:
$ sudo dnf install cmake3
Moreover, you need some extra dependecencies for cross building Windows 64 bits libJVips.dll:
$ sudo dnf install mingw-w64-tools mingw64-gcc mingw64-glib2 mingw64-win-iconv mingw64-expat
Run the build with:
$ ./build.sh
Build options:
- --debug, enable debugging in JVips and its dependencies (default: release mode)
- --without-w64, disable Windows 64 build (default: disable)
- --without-linux, disable Linux build (default: disable)
- --skip-test, disable unit tests (default: enable)
- --run-benchmark, launch benchmark suite (default: disable)
- --minimal, Build 'minimal' maven profile. JVips dependencies aren't embedded in jar file (default: all)
- --jobs N, define make jobs number (default: 8)
Clean project with:
$ ./clean.sh
Install libvips required dependencies.
Install the official Vips binaries:
- Download the 64 bit version of libvips (vips-dev-w64-all-8.7.0.zip) and unzip it
- Set environment variable VIPS_HOME to C:\Program Files\vips-dev-w64-all-8.7.0
- Append $VIPS_HOME/bin and $VIPS_HOME to $PATH environment variable
Run the HelloWorld main in src/example/java/com/criteo/vips/HelloWorld.java. It should open the file 'src/example/ressources/in_vips.jpg', resize image and prints:
INFO: Trying to load JVips
Image has been correctly resized: (1920,1080) -> (960,540)
The following steps explain how to bind a function from libvips. Let's add hasAlpha() method:
- Declare method in VipsImage interface in src/main/java/com/criteo/vips/VipsImage.java
- Declare native method in VipsImageImpl in src/main/java/com/criteo/vips/VipsImageImpl.java
public native boolean hasAlpha();
- Run build.sh to generate JNI header file:
/*
* Class: com_criteo_vips_VipsImageImpl
* Method: hasAlpha
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_criteo_vips_VipsImageImpl_hasAlpha
(JNIEnv *, jobject);
- Define and implement function in src/main/c/VipsImage.c
JNIEXPORT jboolean JNICALL
Java_com_criteo_vips_VipsImageImpl_hasAlpha(JNIEnv *env, jobject obj)
{
VipsImage *im = (VipsImage *) (*env)->GetLongField(env, obj, handle_fid);
return vips_image_hasalpha(im);
}
On an Ubuntu 18.04 VM running with a quad-core Xeon E3-1271 v3 @ 3.6GHz, we apply the following operations:
- open an 1920x1080 jpg image
- resize to 100x100 dimension
- crop a 50x30 rectangle on the top left corner
- pad to a 50x80 image
- write the output image into a buffer
- release resources
Implementation | Run time (ms) | Times slower |
---|---|---|
Vips C 8.7 | 12 | 1.0 |
JVips 1.0 | 22 | 1.83 |
According to this results, JVips is as slower as py-vips.
- Add the missing operations
- Adapt the binding design for calling function by operation name (see also: https://libvips.github.io/libvips/API/current/binding.md.html)
- Publish artifact on the maven central repository