diff --git a/README.md b/README.md index ab934450..82dd58d8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ This project is deployed and used in production at Criteo to serve billions of i Not all libvips capabilities are implemented. JVips currently exposes: - Resize +- Rotate by a multiple of 90 degrees +- Autofix rotation based on image EXIF metadata - Pad - Crop - Find trim (get bounding box) @@ -189,12 +191,13 @@ The following steps explain how to bind a function from `libvips`. Let's add `hasAlpha()` method: -1. Declare method in [`VipsImage`](src/main/java/com/criteo/vips/VipsImage.java) interface -2. Declare native method in [`VipsImageImpl`](src/main/java/com/criteo/vips/VipsImageImpl.java) +1. Declare the method in [`VipsImage`](src/main/java/com/criteo/vips/VipsImage.java) class and + [Image](src/main/java/com/criteo/vips/Image.java) interface +1. Declare the native method in [`VipsImage`](src/main/java/com/criteo/vips/VipsImage.java) class ```java public native boolean hasAlpha(); ``` -3. Run build.sh to generate JNI header file: +1. Run build.sh to generate JNI header file: ```c /* * Class: com_criteo_vips_VipsImageImpl @@ -204,7 +207,7 @@ public native boolean hasAlpha(); JNIEXPORT jboolean JNICALL Java_com_criteo_vips_VipsImageImpl_hasAlpha (JNIEnv *, jobject); ``` -4. Define and implement function in src/main/c/VipsImage.c +1. Define and implement function in [VipsImage.c](src/main/c/VipsImage.c) ```c JNIEXPORT jboolean JNICALL Java_com_criteo_vips_VipsImageImpl_hasAlpha(JNIEnv *env, jobject obj) diff --git a/src/main/c/VipsImage.c b/src/main/c/VipsImage.c index d9f1def9..9d76a63e 100644 --- a/src/main/c/VipsImage.c +++ b/src/main/c/VipsImage.c @@ -796,6 +796,21 @@ JNICALL Java_com_criteo_vips_VipsImage_autorot(JNIEnv *env, jobject image_obj) g_object_unref(im); } +JNIEXPORT void +JNICALL Java_com_criteo_vips_VipsImage_rotNative(JNIEnv *env, jobject image_obj, jint angle) +{ + VipsImage *im = (VipsImage *) (*env)->GetLongField(env, image_obj, handle_fid); + VipsImage *out = NULL; + + if (vips_rot(im, &out, angle, NULL)) + { + throwVipsException(env, "Unable to rotate image"); + return; + } + (*env)->SetLongField(env, image_obj, handle_fid, (jlong) out); + g_object_unref(im); +} + JNIEXPORT jobject JNICALL Java_com_criteo_vips_VipsImage_clone(JNIEnv *env, jobject image_obj) { diff --git a/src/main/c/VipsImage.h b/src/main/c/VipsImage.h index a953fa91..f74a6560 100644 --- a/src/main/c/VipsImage.h +++ b/src/main/c/VipsImage.h @@ -351,6 +351,14 @@ JNIEXPORT jint JNICALL Java_com_criteo_vips_VipsImage_getNbFrame JNIEXPORT void JNICALL Java_com_criteo_vips_VipsImage_autorot (JNIEnv *, jobject); +/* + * Class: com_criteo_vips_VipsImage + * Method: rotNative + * Signature: (I)V + */ +JNIEXPORT void JNICALL Java_com_criteo_vips_VipsImage_rotNative + (JNIEnv *, jobject, jint); + /* * Class: com_criteo_vips_VipsImage * Method: removeAutorotAngle diff --git a/src/main/java/com/criteo/vips/Image.java b/src/main/java/com/criteo/vips/Image.java index 1e76a775..3c664aa6 100644 --- a/src/main/java/com/criteo/vips/Image.java +++ b/src/main/java/com/criteo/vips/Image.java @@ -365,6 +365,13 @@ public interface Image extends AutoCloseable { */ void autorot() throws VipsException; + /** + * Rotates the image by a multiple of 90 degrees + * + * @throws VipsException if error + */ + void rot(VipsAngle angle) throws VipsException; + /** * Remove the orientation tag on the image */ diff --git a/src/main/java/com/criteo/vips/VipsImage.java b/src/main/java/com/criteo/vips/VipsImage.java index 984a5c88..15c9d800 100644 --- a/src/main/java/com/criteo/vips/VipsImage.java +++ b/src/main/java/com/criteo/vips/VipsImage.java @@ -328,6 +328,12 @@ public VipsInterpretation getInterpretation() { public native void autorot() throws VipsException; + public void rot(VipsAngle angle) throws VipsException { + rotNative(angle.getValue()); + } + + public native void rotNative(int angle) throws VipsException; + public native void removeAutorotAngle(); public native VipsImage clone() throws VipsException; diff --git a/src/test/java/com/criteo/vips/VipsImageTest.java b/src/test/java/com/criteo/vips/VipsImageTest.java index f0f5e1d6..2ca03bcf 100644 --- a/src/test/java/com/criteo/vips/VipsImageTest.java +++ b/src/test/java/com/criteo/vips/VipsImageTest.java @@ -895,6 +895,19 @@ public void TestExif90CWAutorot() throws IOException, VipsException { } } + @Test + public void TestD90Rot() throws IOException, VipsException { + ByteBuffer buffer = VipsTestUtils.getDirectByteBuffer("in_vips.jpg"); + + try (VipsImage img = new VipsImage(buffer, buffer.capacity())) { + int width = img.getWidth(); + int height = img.getHeight(); + img.rot(VipsAngle.D90); + assertEquals(width, img.getHeight()); + assertEquals(height, img.getWidth()); + } + } + @Test public void TestCreateVipsImageFromFile() throws IOException, VipsException { String filename = VipsTestUtils.getRessourcePath("in_vips.jpg");