XUtils

TwelveMonkeys

Collection of plugins that extend the number of supported image file formats.


Using the ResampleOp

The library comes with a resampling (image resizing) operation, that contains many different algorithms to provide excellent results at reasonable speed.

import com.twelvemonkeys.image.ResampleOp;

...

BufferedImage input = ...; // Image to resample
int width, height = ...; // new width/height

BufferedImageOp resampler = new ResampleOp(width, height, ResampleOp.FILTER_LANCZOS); // A good default filter, see class documentation for more info
BufferedImage output = resampler.filter(input, null);

Using the DiffusionDither

The library comes with a dithering operation, that can be used to convert BufferedImages to IndexColorModel using Floyd-Steinberg error-diffusion dither.

import com.twelvemonkeys.image.DiffusionDither;

...

BufferedImage input = ...; // Image to dither

BufferedImageOp ditherer = new DiffusionDither();
BufferedImage output = ditherer.filter(input, null);

Building

Download the project (using Git):

$ git clone git@github.com:haraldk/TwelveMonkeys.git

This should create a folder named TwelveMonkeys in your current directory. Change directory to the TwelveMonkeys folder, and issue the command below to build.

Build the project (using Maven):

$ mvn package

Currently, the recommended JDK for making a build is Oracle JDK 8.x.

It’s possible to build using OpenJDK, but some tests might fail due to some minor differences between the color management systems used. You will need to either disable the tests in question, or build without tests altogether.

Because the unit tests needs quite a bit of memory to run, you might have to set the environment variable MAVEN_OPTS to give the Java process that runs Maven more memory. I suggest something like -Xmx512m -XX:MaxPermSize=256m.

Optionally, you can install the project in your local Maven repository using:

$ mvn install

Installing

To install the plug-ins, either use Maven and add the necessary dependencies to your project, or manually add the needed JARs along with required dependencies in class-path.

The ImageIO registry and service lookup mechanism will make sure the plugins are available for use.

To verify that the JPEG plugin is installed and used at run-time, you could use the following code:

Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JPEG");
while (readers.hasNext()) {
    System.out.println("reader: " + readers.next());
}

The first line should print:

reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@somehash

Maven dependency example

To depend on the JPEG and TIFF plugin using Maven, add the following to your POM:

...
<dependencies>
    ...
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-jpeg</artifactId>
        <version>3.10.1</version>
    </dependency>
    <dependency>
        <groupId>com.twelvemonkeys.imageio</groupId>
        <artifactId>imageio-tiff</artifactId>
        <version>3.10.1</version>
    </dependency>

    <!--
    Optional dependency. Needed only if you deploy ImageIO plugins as part of a web app.
    Make sure you add the IIOProviderContextListener to your web.xml, see above.
    -->
    <dependency>
        <groupId>com.twelvemonkeys.servlet</groupId>
        <artifactId>servlet</artifactId>
        <version>3.10.1</version>
    </dependency>

    <!--
    Or Jakarta version, for Servlet API 5.0
    -->
    <dependency>
        <groupId>com.twelvemonkeys.servlet</groupId>
        <artifactId>servlet</artifactId>
        <version>3.10.1</version>
        <classifier>jakarta</classifier>
    </dependency>
</dependencies>

Manual dependency example

To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:

twelvemonkeys-common-lang-3.10.1.jar
twelvemonkeys-common-io-3.10.1.jar
twelvemonkeys-common-image-3.10.1.jar
twelvemonkeys-imageio-core-3.10.1.jar
twelvemonkeys-imageio-metadata-3.10.1.jar
twelvemonkeys-imageio-jpeg-3.10.1.jar
twelvemonkeys-imageio-tiff-3.10.1.jar

Including the plugins in a “fat” JAR

The recommended way to use the plugins, is just to include the JARs as-is in your project, through a Maven dependency or similar. Re-packaging is not necessary to use the library, and not recommended.

However, if you like to create a “fat” JAR, or otherwise like to re-package the JARs for some reason, it’s important to remember that automatic discovery of the plugins by ImageIO depends on the Service Provider Interface (SPI) mechanism. In short, each JAR contains a special folder, named META-INF/services containing one or more files, typically javax.imageio.spi.ImageReaderSpi and javax.imageio.spi.ImageWriterSpi. These files exist with the same name in every JAR, so if you simply unpack everything to a single folder or create a JAR, files will be overwritten and behavior be unspecified (most likely you will end up with a single plugin being installed).

The solution is to make sure all files with the same name, are merged to a single file, containing all the SPI information of each type. If using the Maven Shade plugin, you should use the ServicesResourceTransformer to properly merge these files. You may also want to use the ManifestResourceTransforme to get the correct vendor name, version info etc. Other “fat” JAR bundlers will probably have similar mechanisms to merge entries with the same name.


Articles

  • coming soon...