Reputation: 4821
I'm trying to display an Image that is bigger than the JFrame Dimensions. If I try to resize the Image smaller, then the Image quality is lost.
If I make the Image larger, the quality is not lost. Is this normal behavior in Java image package?
I guess what I'm trying to figure out is that probably I'm doing something wrong when reducing the Image size. So does Java provide a method to automatically do this without loosing image quality?
Same behavior like JButtons, where java automatically adjusts the space occupied by a JButton in a JPanel.
bufferedImage = resize(bufImage,500,600);
ImageIcon imageIcon = new ImageIcon(bufferedImage);
resizedIMage = imageIcon.getImage();
The actual resize is below. I took it from the internet.
private static BufferedImage resize(BufferedImage image, int width, int height) {
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
Upvotes: 1
Views: 3033
Reputation: 5980
If you are using Java 5 or newer you can try RenderingHints.VALUE_INTERPOLATION_BICUBIC for your interpolation hint.
There is a very detailed description of the different scaling behaviours of Java2D in this article: perils-of-getScaledInstance
It contains examples of the different downscale results you can expect to see with the different approaches available in Java.
It also provides sample code that uses a multi-step aproach to downscale the image which appears to produce much better results than VALUE_INTERPOLATION_BILINEAR.
Upvotes: 2
Reputation: 53521
Override the paintComponent(Graphics g)
method of whatever component will display the image and look at Graphics.drawImage()
You can even cast your Graphics
instance into a Graphics2D for more functionalities. For example setRenderingHings()
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh = g2.getRenderingHints ();
rh.put (RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints (rh);
Upvotes: 1
Reputation: 538
I would get rid of this:
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
And always use BufferedImage.TYPE_INT_ARGB
That seems to give me good results.
Upvotes: 0