I have two services which trade binary data from an original heic/heif image via redis (binary safe). Since ImageIo does not support that image type I built a separate service in nodejs, which just converts heic/heif images to jpegs. After conversion on the nodejs service it saves the string encoded (latin1) image bytes again in Redis where the other service (javax.imagio) retrieves it, decodes the string back to bytes and tries to read from it. On that point I recveive the following exception:
java.lang.IllegalArgumentException: Empty region!
at java.desktop/javax.imageio.ImageReader.computeRegions(ImageReader.java:2687)
I am no way an expert for image processing, so I would be happy if someone could explain what I am doing wrong. Below you can see my code:
My string serializer:
public static Optional<String> encodeBytesToString(byte[] data) {
return Optional.ofNullable((data == null ? null : new String(data, StandardCharsets.ISO_8859_1)));
}
public static byte[] decodeStringToBinary(String string) {
return (string == null ? null : string.getBytes(StandardCharsets.ISO_8859_1));
}
Business logic
BufferedImage image = imageService.readImage(decodeStringToBinary(convertedImage.getData()));
Reader:
public BufferedImage readImage(byte[] data) throws IOException {
return ImageIO.read(new ByteArrayInputStream(data));
}
The docs of the computeRegions method (where the exception is thrown) states the following:
If either the source or destination regions end up having a width or height of 0, an IllegalArgumentException is thrown.
No idea why these properties are 0. I use the following lib for the nodejs service: https://github.com/catdad-experiments/heic-convert It works if you use the example in the readme, which saves the outputbuffer to disk. I wanted to skip that and just pass the bytes to redis directly. Am I doing something fundamentally wrong or whats going on here?
Below the code on nodejs:
const outputBuffer = await convert({
buffer: inputBuffer,
format: OutputFormatEnum.JPEG,
quality: 1,
});
const encodedBin: string = await this.encodeToStringBinary(
Buffer.from(outputBuffer),
);
this.redisCache.hset(fileId, encodedBin);