All formats

TwelveMonkeys ImageIO WebP

LanguageJava 8+
LicenseBSD-3-Clause
Repositorygithub.com/haraldk/TwelveMonkeys
DocumentationREADME
Depends onTwelveMonkeys common libraries (pulled in by Maven/Gradle), no native code
Read / writeyes / no; lossy, lossless, alpha

TwelveMonkeys is a collection of ImageIO plugins (TIFF, PSD, WebP, ICNS, PICT, …). The imageio-webp module is a WebP decoder written in pure Java: no JNI, so it runs on any JVM and OS, including Alpine containers and unusual architectures. It reads lossy (VP8), lossless (VP8L) and transparent images.

It can’t write WebP. To write, add webp-imageio or convert with another tool.

Installation#

Maven:

XML
<dependency>
  <groupId>com.twelvemonkeys.imageio</groupId>
  <artifactId>imageio-webp</artifactId>
  <version>3.15.0</version>
</dependency>

Gradle:

Kotlin
implementation("com.twelvemonkeys.imageio:imageio-webp:3.15.0")

In web applications add com.twelvemonkeys.servlet:servlet and register IIOProviderContextListener so plugins are found and unloaded with the app.

Basic usage: convert WebP to PNG#

The plugin registers itself through the service loader, so plain ImageIO code works:

Java
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedImage image = ImageIO.read(new File("in.webp"));
        if (image == null) throw new IOException("no WebP reader on the classpath");
        System.out.println(image.getWidth() + " x " + image.getHeight()
                + ", alpha: " + image.getColorModel().hasAlpha());
        ImageIO.write(image, "png", new File("out.png"));
    }
}

How to convert WebP to JPEG#

JPEG has no alpha, so draw the image on an opaque background first:

Java
import java.awt.Color;
import java.awt.Graphics2D;

BufferedImage webp = ImageIO.read(new File("in.webp"));
BufferedImage rgb = new BufferedImage(webp.getWidth(), webp.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g = rgb.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, rgb.getWidth(), rgb.getHeight());
g.drawImage(webp, 0, 0, null);
g.dispose();
ImageIO.write(rgb, "jpg", new File("out.jpg"));

How to get WebP dimensions without decoding#

Java
import java.util.Iterator;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

try (ImageInputStream in = ImageIO.createImageInputStream(new File("in.webp"))) {
    Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
    if (!readers.hasNext()) throw new IOException("not a supported image");
    ImageReader reader = readers.next();
    try {
        reader.setInput(in);
        System.out.println(reader.getFormatName() + ": " + reader.getWidth(0) + " x " + reader.getHeight(0));
    } finally {
        reader.dispose();
    }
}

How to decode a thumbnail faster#

ImageIO’s subsampling skips pixels while decoding:

Java
import javax.imageio.ImageReadParam;

ImageReader reader = ImageIO.getImageReadersByFormatName("webp").next();
try (ImageInputStream in = ImageIO.createImageInputStream(new File("in.webp"))) {
    reader.setInput(in);
    ImageReadParam param = reader.getDefaultReadParam();
    param.setSourceSubsampling(4, 4, 0, 0);  // every 4th pixel in each direction
    BufferedImage small = reader.read(0, param);
} finally {
    reader.dispose();
}