Attempting to downsample (interpolate) an image containing text and other sharp edges can lead to some messy results.
Bicubic downsampling doesn't seem to cut it in this case:
private BufferedImage createResizedCopyBicubic(BufferedImage source, int destWidth, int destHeight) {
BufferedImage bicubic = new BufferedImage(destWidth, destHeight, source.getType());
Graphics2D bg = bicubic.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
float sx = (float)destWidth / source.getWidth();
float sy = (float)destHeight / source.getHeight();
bg.scale(sx, sy);
bg.drawImage(source, 0, 0, null);
bg.dispose();
return bicubic;
}
Instead making use of the Java Advanced Imaging APIs and using average downsample yields a much nicer result:
private BufferedImage createResizedCopyAveraging(BufferedImage source, double scaleX, double scaleY) {
RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
RenderedOp resizeOp = SubsampleAverageDescriptor.create(source, scaleX, scaleY, hints);
return resizeOp.getAsBufferedImage();
}