Home > Back-end >  How to Resize an Image in Swing?
How to Resize an Image in Swing?

Time:05-20

I've learnt how to add an image in Javax swing a lot of times. I've used containers and all imageicons, however the problem is that my photos are too large to fit in. They are above 1800*1700 pixels in size and the screen obviously can't accomodate them. I would request you guys to suggest a way to scale the image down. Just FYI, I've tried most of these methods like using awt Image, setBounds, SCALE_DEFAULT and stuff. For some reason, my IDE, BlueJ doesn't seem to work with a lot of the methods which are suggested, still I would request you to please help me. Here is the code:

import javax.swing.*;
import java.awt.*;


class JLabelDemo
{
public JLabelDemo()
{
    JFrame jfrm=new JFrame("Image from book");
    jfrm.setLayout(new FlowLayout());
    jfrm.setDefaultCloseOperation(jfrm.EXIT_ON_CLOSE);
    jfrm.setSize(500,700);
    
    ImageIcon ii=new ImageIcon("D:\\Dhruv Rana\\UNATIS Mandarmoni Trip\\Sunrise.jpg");
    JLabel jl=new JLabel("Background",ii,JLabel.CENTER);
    jfrm.add(jl);
    jfrm.setVisible(true);
}
public static void main(String [] args)
{
    SwingUtilities.invokeLater(
    new Runnable()
    {
        public void run()
        {
            new JLabelDemo();
        }
    }
    );
}
}

CodePudding user response:

put it in an bufferedImage

Graphics2D grph = image.createGraphics();
grph.scale(2.0, 2.0);
grph.dispose();

Or look at How to scale a BufferedImage

CodePudding user response:

I suppose it depends upon whether or not you want to maintain the Aspect Ratio of the image you are loading into the JLabel.

In any case, below is a runnable which takes Aspect Ratio into account so that the images don't look distorted (elongated, etc) when displayed. The JFrame window is automatically sized in accordance with the Image Aspect Ratio so as to maintain the desired form size in either portrait or landscape depending on the image to be displayed. If the image is in portrait format, so will be the JFrame window. If the image is in Landscape format, so to will the JFrame window.

Two methods of interest are the resizeImageIcon() and getAspectRatioDimension() methods. Be sure to read the comments in code.

Here is the code:

import java.awt.*;
import javax.swing.*;

public class JLabelDemo {

    public JLabelDemo() {
        int figNum = 1;     // Image figure number (optional)
        // Load in the Image
        ImageIcon ii = new ImageIcon("D:\\Dhruv Rana\\UNATIS Mandarmoni Trip\\Sunrise.jpg");
        
        /* Get the Aspect Ratio of the image in relation to the 
           desired size of JFrame form (500 x 700)        */
        java.awt.Dimension aspectDimensions = getAspectRatioDimension(
                           ii.getIconWidth(), ii.getIconHeight(), 500, 700);
        
        // Create the Window
        JFrame jfrm = new JFrame("Image from book");
        jfrm.setLayout(new FlowLayout());
        jfrm.setAlwaysOnTop(true);  // Form will always be on top of other wondows.
        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        /* Set the form's size in accordance to the Aspect Ratio.
           40 is added to the hieght so as to accommodate for the
           JLabel text.        */
        jfrm.setSize(aspectDimensions.width, aspectDimensions.height   40);
        jfrm.setResizable(false); // Make form non-sizable
        
        /* Resise the image in accordance to the Aspect Ratio
           less 30 so as not to hug the edge of Window.    */
        ii = resizeImageIcon(ii, aspectDimensions.width - 30, aspectDimensions.height - 30);
        
        // Create the JLabel and apply the image
        JLabel jl = new JLabel("", ii, JLabel.CENTER);
        
        // Un-comment if you want a border on the JLabel.
        //jl.setBorder(BorderFactory.createLineBorder(Color.blue, 1));
        
        // Set the JLabel text below the Image and at center.
        jl.setVerticalTextPosition(JLabel.BOTTOM);
        jl.setHorizontalTextPosition(JLabel.CENTER);
        
        // Provide the JLabel text (basic HTML is used here to add a little pizaze) 
        jl.setText("<html><font size='2' color=gray><i>Figure "   figNum   ":&nbsp;&nbsp; Background</i></font></html>");
        
        jfrm.add(jl);
        jfrm.pack();
        jfrm.setLocationRelativeTo(null);   // Set window to center Screen.
        jfrm.setVisible(true);              // Display Window
        
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JLabelDemo();
            }
        });
    }
    
    public static javax.swing.ImageIcon resizeImageIcon(javax.swing.ImageIcon icon, int resizedWidth, int resizedHeight) {
        java.awt.Image img = icon.getImage();
        java.awt.Image resizedImage = img.getScaledInstance(resizedWidth, resizedHeight, java.awt.Image.SCALE_SMOOTH);
        return new javax.swing.ImageIcon(resizedImage);
    }
    
    /**
     * This method will retrieve the required dimensions in order to maintain
     * the aspect ratio between the original dimensions and the desired
     * dimensions.<br><br>
     * <p>
     * <b>Example Usage:</b><pre>
     *
     *          Dimension dim = getAspectRatioDimension(500, 300, 200, 200);
     *          System.out.println("Width = "   dim.width   "  ---  Height = "   dim.height);
     *          // Output will be:  Width = 200  ---  Height = 120</pre>
     *
     * @param currentWidth  (Integer) The width of current dimension to convert
     *                      from.
     * @param currentHeight (Integer) The height of current dimension to convert
     *                      from.
     * @param desiredWidth  (Integer) The width we want to convert to.
     * @param desiredHeight (Integer) The height we want to convert to.
     *
     * @return (Dimension) The actual width & height dimensions we need to
     *         maintain the Aspect Ratio from the original current dimensions.
     */
    public java.awt.Dimension getAspectRatioDimension(final int currentWidth, 
            final int currentHeight, final int desiredWidth, final int desiredHeight) {
        int original_width = currentWidth;
        int original_height = currentHeight;
        int bound_width = desiredWidth;
        int bound_height = desiredHeight;
        int new_width = original_width;
        int new_height = original_height;

        // first check if we need to scale width
        if (original_width > bound_width) {
            //scale width to fit
            new_width = bound_width;
            //scale height to maintain aspect ratio
            new_height = (new_width * original_height) / original_width;
        }

        // then check if we need to scale even with the new height
        if (new_height > bound_height) {
            //scale height to fit instead
            new_height = bound_height;
            //scale width to maintain aspect ratio
            new_width = (new_height * original_width) / original_height;
        }
        return new java.awt.Dimension(new_width, new_height);
    }
    
}
  • Related