Tuesday, August 14, 2007
Keeping Simple Things Simple
For example: I want to read an image, make it smaller, and write it out as a JPG with a given quality. This is a fairly common and simple task. Here's the code:
BufferedImage sourceImage
try {
sourceImage = ImageIO.read(new ByteArrayInputStream(imageData));
} catch (IOException e) {
return new ServiceResult(ServiceResult.STATUS.FAIL_HARD,
"Unable to read image; image is unreadable or an unsupported type", e);
}
// figure out the target width and height
BufferedImage newImage = getScaledInstance(sourceImage, targetWidth, targetHeight, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);
ByteArrayOutputStream output = new ByteArrayOutputStream();
IteratorimageWritersByMIMEType = ImageIO.getImageWritersByMIMEType("image/jpeg");
if (imageWritersByMIMEType.hasNext()) {
ImageWriter writer = imageWritersByMIMEType.next();
writer.setOutput(new MemoryCacheImageOutputStream(output));
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(COMPRESSION_QUALITY);
IIOImage tmpImage = new IIOImage(newImage, null, null);
try {
writer.write(null, tmpImage, iwp);
} catch (IOException e) {
return new ServiceResult(ServiceResult.STATUS.FAIL_HARD, "Exception while creating jpeg content", e);
}
} else {
return new ServiceResult(ServiceResult.STATUS.FAIL_HARD, "Couldn't find a jpeg encoder!");
}
return new ServiceResult(ServiceResult.STATUS.OK, "Created avatar successfully", output.toByteArray());
So we had to use: BufferedImage, ImageIO, ByteArrayInputStream, ByteArrayOutputStream, Graphics2D (inside the getScaledInstance method), ImageWriter, ImageWriteParam, MemoryCacheImageOutputStream and IIOImage. (Not counting any java.lang, java.util or exception stuff.)
Why can't ImageIO read a byte array? (I can almost forgive the design decision to work mainly with streams.) Why does an ImageWriter need to write to a MemoryCacheImageOutputStream (an ordinary OutputStream won't do)? What's with ImageWriter#setOutput taking an Object? Do we really expect to have multiple image writers for a given MIME type such that we need an iterator? Why can't an ImageWriter write a BufferedImage? Why is there a getDefaultWriteParam, if that's the only WriteParam there is to get?
javax.imageio has got to be the absolutely most retarded API I have seen to date, with the closest runner-up being jTidy.
Labels: api, javax.imageio, overengineering, software, stupid
Subscribe to Posts [Atom]