Marquinio
Marquinio

Reputation: 4821

Fit Java Image into JFrame

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

Answers (3)

Aaron
Aaron

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

Yanick Rochon
Yanick Rochon

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

Pat L
Pat L

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

Related Questions