o7planning

Java Sejda WebP ImageIO convert Images to WEBP

  1. Library
  2. Examples
WebP is a new generation image format developed by Google specifically for the Web. It supports compression without loss of image quality (lossless compression) and with loss of image quality (lossy compression).
Compared to commonly used formats like JPEG, WebP has 25%-34% smaller file sizes with the same quality. WebP offers better compression and reduced file sizes, which is important for the web because every byte of data saved matters.
  • WEBP image format
  • lossless compression vs lossy compression
In this article, I show you how to use the Java Sejda WebP ImageIO library to convert other image formats to WebP.

1. Library

Dependencies:
porm.xml
<!-- Java Lib for Image WebP -->
<!-- https://mvnrepository.com/artifact/org.sejda.webp-imageio/webp-imageio-sejda -->
<dependency>
    <groupId>org.sejda.webp-imageio</groupId>
    <artifactId>webp-imageio-sejda</artifactId>
    <version>0.1.0</version> 
</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
	<groupId>commons-io</groupId>
	<artifactId>commons-io</artifactId>
	<version>2.11.0</version>
</dependency>

2. Examples

For simplicity, we write a class with utility methods that convert image formats to WebP:
WebpUtils.java
package org.o7planning.java_14179_webp;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageOutputStream;

import com.luciad.imageio.webp.WebPWriteParam;

public class WebpUtils {

	public static byte[] imageBytesToWebpBytes(byte[] imageBytes) throws IOException {
		InputStream is = new ByteArrayInputStream(imageBytes);
		BufferedImage image = ImageIO.read(is);
		//
		// Obtain a WebP ImageWriter instance
		ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();

		// Configure encoding parameters
		WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
		writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
		writeParam.setCompressionType(writeParam.getCompressionTypes()[WebPWriteParam.LOSSLESS_COMPRESSION]);

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ImageOutputStream ios = ImageIO.createImageOutputStream(baos);

		// Configure the output on the ImageWriter
		writer.setOutput(ios);
		writer.write(null, new IIOImage(image, null, null), writeParam);
		ios.flush();

		return baos.toByteArray();
	}

	public static void imageFileToWebpImageFile(File inputFile, File webpOutputFile) throws IOException {
		FileInputStream fis = new FileInputStream(inputFile);
		BufferedImage image = ImageIO.read(fis);

		ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();

		WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
		// Notify encoder to consider WebPWriteParams
		writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
		// Set lossless compression
		writeParam.setCompressionType(writeParam.getCompressionTypes()[WebPWriteParam.LOSSLESS_COMPRESSION]);

		// Save the image
		writer.setOutput(new FileImageOutputStream(webpOutputFile));
		writer.write(null, new IIOImage(image, null, null), writeParam);
	}
}
In the above code, you need to pay attention to the optional parameter:
  • WebPWriteParam.LOSSLESS_COMPRESSION
  • WebPWriteParam.LOSSY_COMPRESSION
WebPWriteParam
Description
LOSSLESS_COMPRESSION
Convert image to WEBP format without losing image quality. This option will compress the image to create a new image file with a smaller size, and when decompressed all the original data will be restored.
LOSSY_COMPRESSION
Convert image to WEBP format with slightly reduced image quality. In other words, this option will compress the image to create a new image file with a smaller size while also removing some unnecessary data. Once decompressed the original data will not be restored.
This data loss is not usually noticeable. However, the more a file is compressed, the more degradation occurs, and the loss eventually becomes visible.
LOSSY_COMPRESSION
In case you compress images with the LOSSY_COMPRESSION parameter, you can specify the image quality you expect via the setCompressionQuality method:
//
// Set lossy compression
//
writeParam.setCompressionType(writeParam.getCompressionTypes()[WebPWriteParam.LOSSY_COMPRESSION]);
//
// Compression Quality: 50%.
//
writeParam.setCompressionQuality(0.5f);
Finally, we use the utility methods above to convert a PNG image file into a WEBP:
MainTest1.java
package org.o7planning.java_14179_webp;

import java.io.File;
import java.io.IOException;

public class MainTest1 { 

	public static void main(String[] args) throws IOException {
		File inputFile = new File("/Volumes/New/Test/pngFile.png");

		File webpOutputFile = new File("/Volumes/New/Test/output/webpFile1.webp");
		webpOutputFile.getParentFile().mkdirs();

		WebpUtils.imageFileToWebpImageFile(inputFile, webpOutputFile);
		System.out.println("Done!");
	} 
}
MainTest2.java
package org.o7planning.java_14179_webp;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

public class MainTest2 {

	public static void main(String[] args) throws IOException {
		File inputFile = new File("/Volumes/New/Test/pngFile.png");
		// Common IO.
		byte[] imageBytes = FileUtils.readFileToByteArray(inputFile);

		// Webp byte array:
		byte[] webpImageBytes = WebpUtils.imageBytesToWebpBytes(imageBytes);

		File webpOutputFile = new File("/Volumes/New/Test/output/webpFile2.webp");

		FileUtils.writeByteArrayToFile(webpOutputFile, webpImageBytes);
		System.out.println("Done!");
	} 
}