Java ImageIcon大小

17

我已经在我的GUI中上传了一张图片,并将其显示在JLabel上。标签的尺寸仅设置为100,100,而图片却要大得多,因此当我将其上传到标签时,它会扩展。

是否有任何方法可以使它自动调整大小以适应标签的尺寸?

以下是“上传图片”JButton的操作监听器

class UploadHandler implements ActionListener 
{
    public void actionPerformed(ActionEvent e)
    {
        int returnVal = fc.showOpenDialog(frame2);
        file = fc.getSelectedFile();
        pathname = file.getPath();
        icon = new ImageIcon(pathname);
        lblDisPic.setIcon(icon);    
    }
}

btnUpload = new JButton("Upload Picture");
lblDisPic = new JLabel();
lblDisPic.setBorder(raisedetched);
lblDisPic.setPreferredSize(d); 

btnUpload.addActionListener(new UploadHandler());
5个回答

27

给出这个例子代码,一种方法是在调用setIcon方法之前将图像大小调整到适合JLabel上显示。

一种方法可以是更改actionPerformed方法,因此将从指定的文件加载图像,使用ImageIO.read方法读取图像,然后调整图像大小以创建ImageIcon

Image img = ImageIO.read(fc.getSelectedFile());

接着,可以使用Image.getScaledInstance将加载的图像调整大小到JLabel的尺寸。

Image resizedImage = 
    img.getScaledInstance(lblDisPic.getWidth(), lblDisPic.getHeight(), null);

现在,可以创建一个ImageIcon并将其用于JLabel上。

lblDisPic.setIcon(new ImageIcon(resizedImage));

这种方法的限制是,如果JLabel以任何方式被调整大小,那么JLabel包含的图像将不会被调整大小。然而,由于JLabel将使用原始图像的缩小版本,这意味着所需的内存量将减少(如果考虑到这一点),并且原始图像不必每次显示图像时都被调整大小,这与覆盖paintComponent方法的情况不同。

实现手头任务的首选方法将取决于是否需要稍后再使用原始图像的要求。


你好,是的,需要再次使用图像来显示个人信息。 - sutoL
7
我认为应该将null替换为Image.SCALE_FAST(或其枚举变体之一)。 - sdasdadas
或者使用 Image.SCALE_SMOOTH,它会尝试更平滑地缩放图像(文档中说:选择一种图像缩放算法,它将更高的优先级赋予图像平滑度而不是缩放速度。) - Markus Weninger

7
当然,只需覆盖paintComponent方法,您就可以按照所需的方式进行缩放和绘制。
myLabel = new JLabel (/*whatever*/) {

    @Override
    public void paintComponent (Graphics g) {
        super.paintComponent (g);
        g.drawImage (myImageIcon.getImage(), 0, 0, getWidth (), getHeight (), null);
    }
};

这里是源链接

编辑

为了补充你的代码更改:

lblDisPic = new JLabel();

致:

lblDidPic = new JLabel() {

    @Override
    public void paintComponent (Graphics g) {
        super.paintComponent (g);
        if (icon != null) {
            g.drawImage (icon.getImage(), 0, 0, getWidth(), getHeight(), null);
        }
    }
};

抱歉,我不太理解匿名内部类的作用,请问您能告诉我如何实现它吗? - sutoL
我的 ActionListener 类 UploadHandler 怎么样? - sutoL

2

您可以在图标本身上覆盖paintIcon方法 -

ImageIcon icon = new ImageIcon(...) {

    @Override
    public void paintIcon( Component c, Graphics g, int x, int y ) {
        g.drawImage(getImage(), x, y, c.getWidth(), c.getHeight(), c);
    }

    @Override 
    public int getIconHeight() {
        // see below...
    }

    @Override
    public int getIconWidth() {
        // see below...
    }

};

编辑 -

我意识到标签在决定图标的 x,y 位置时考虑了图像的原始大小。您还需要覆盖 getIconWidth() 和 getIconHeight() 方法。

但是,要覆盖这些方法以返回标签的大小并不容易,因为这些方法中没有对组件本身的引用。

一种方法是创建一个扩展 ImageIcon 的新类,并将组件传入该类 - 这不是一个很好的选择,因为它破坏了图标“在许多组件之间可重用”的特性。

另一种方法是在内部类中像上面那样覆盖这些方法,但将组件作为对象字段或 final 局部变量设置为硬编码引用。同样,这会破坏图标“在许多组件之间可重用”的特性,在一次性内部类中使用可能是可以接受的。


1
如果您可以在画图中编辑图像,那么请在画图中设置其大小,然后单击保存,然后相同大小的图像将出现在您的JAVA应用程序中。

0
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

JFileChooser jFileChooser1=new JFileChooser();

int state = jFileChooser1.showOpenDialog(new JFrame());         
       jTextField1.setText("");

           if( state ==JFileChooser.APPROVE_OPTION) {
      JOptionPane.showMessageDialog(
                    null,null);
         File file = jFileChooser1.getSelectedFile();
         s2=file.toString();
          jTextField1.setText(s2);
       jLabel1=new JLabel();
     jLabel1.setName(s2);
  jLabel1.setLocation(50,50);
  jLabel1.setSize(300,300);
    add(jLabel1);

    BufferedImage bi1;

    try
    {   
        bi1=ImageIO.read(file);
        ImageIcon icon1=new ImageIcon(bi1);
        jLabel1.setIcon(icon1);
        Image img = ImageIO.read(jFileChooser1.getSelectedFile());

        Image resizedImage = 
   img.getScaledInstance(jLabel1.getWidth(), jLabel1.getHeight(),Image.SCALE_DEFAULT);
       jLabel1.setIcon(new ImageIcon(resizedImage)); 


  jLabel1.setBorder(BorderFactory.createLineBorder(Color.RED,5));


       pack();   

    }
    catch(Exception e)
    {
  System.out.println(e);
    }


    }
    else if(state == JFileChooser.CANCEL_OPTION) {
      JOptionPane.showMessageDialog(
                  new JFrame(), "Canceled");
    }
  pack();           

  }

这将显示文件选择器组件,并将图像路径设置在jTextField1中,并使用setIcon显示图像,并调整图像大小以达到预定义的值,以便图像不会被裁剪或显示错误。 - Rohit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接