It's just the nature of image scaling that there is going to be some loss of information.
java.awt.Image has a method, getScaledImage(), which gives you some control over the quality of the scaling through the third parameter, hints. Unfortunately it does not return a BufferedImage, so it is still necessary to create a BufferedImage instance and paint the image onto its Graphics instance. I don't know if this would give you better or worse results than your current code. Try it both ways and compare the results.