缩放后,如果没有不相关的imageIcon,将无法显示图像

时间:2013-08-08 05:54:52

标签: java swing jlabel bufferedimage imageicon

我正在尝试为我正在写的国际象棋程序获取一些图像。我尝试编写一个小程序只是为了感觉缩放图像,我遇到了图像显示的问题。基本上,只有ImageIcon(图标)在那里并且它在代码中的pawn上方时,图像才会正确显示。如果它不存在,则它在代码中的pawn下面,或者图像源是不同的pawn显示为黑色方块。如果我不尝试缩放pawn,那么无论图标是否存在,整个过程都可以正常工作。这一切都让我感到困惑,因为唯一的关​​联典当和图标是他们共享一个源图像。任何人都可以对此有所了解吗?

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.*;



public class resizeImg extends JFrame{

     public void generateGui(){
        JPanel mainPanel=new JPanel();
        getContentPane().add(mainPanel);

        JPanel main=new JPanel();
        main.setBorder(BorderFactory.createLineBorder(new Color(0,0,0)));
        main.setSize(400,400);
        mainPanel.add(main);
        mainPanel.setLayout(null);

        ImageIcon icon=new ImageIcon(Toolkit.getDefaultToolkit().getImage("resources/pawn.jpg"));
        //if you remove the above ImageIcon the image just displays as a black square

        Image pawn=scale(Toolkit.getDefaultToolkit().getImage("resources/pawn.jpg"));
        JLabel pawnContainer=new JLabel(new ImageIcon(pawn));
        main.add(pawnContainer);

        setSize(400,400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public BufferedImage scale(Image i){
        BufferedImage resized=new BufferedImage(50,50,BufferedImage.TYPE_INT_RGB);
        Graphics2D g=resized.createGraphics();
        g.drawImage(i,0,0,50,50,null);
        g.dispose();
        return resized;
    }
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                resizeImg imgObject=new resizeImg();
                imgObject.generateGui();
                imgObject.setVisible(true);
            }
        });
    }
}

1 个答案:

答案 0 :(得分:2)

原始图像加载代码旨在通过慢速网络加载到图像,因此它使用后台线程加载图像。这意味着当Toolkit.getImage返回时,图像可能实际上没有开始加载。

当您加入ImageIcon来电时,ImageIcon正在使用MediaTrackerwaitFor图片加载。由于Toolkit.getImage的缓存机制,对同一图像的重复调用可以使用缓存的图像。

这也是为什么在绘制图像时使用ImageObserver很重要的原因,但在这种情况下它可能对您没有帮助。

相反,请使用ImageIO

public class Scale extends JFrame {

    public void generateGui() {
        JPanel main = new JPanel();
        main.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
        main.setLayout(new BorderLayout());

        try {
            BufferedImage image = ImageIO.read(new File("path/to/image"));

            Image pawn = scale(image);
            JLabel pawnContainer = new JLabel(new ImageIcon(pawn));
            main.add(pawnContainer);
        } catch (IOException exp) {
            exp.printStackTrace();
        }

        add(main);

        setSize(400, 400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public BufferedImage scale(Image i) {
        BufferedImage resized = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resized.createGraphics();
        g.drawImage(i, 0, 0, 50, 50, this);
        g.dispose();
        return resized;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Scale imgObject = new Scale();
                imgObject.generateGui();
                imgObject.setVisible(true);
            }
        });
    }
}