java - 在 BufferedImage 上绘制 Image 对象以供以后使用

标签 java image panel bufferedimage drawimage

我需要一些帮助来在 BufferedImage 上/内部/上绘制 Image 对象,然后在 JPanel 上绘制该 BufferedImage。

我准备了一个小程序来说明我的问题。只是一个带有面板和 ImageLoader 的框架。

图像与代码放置在同一文件夹中。刚绘制时,sten 图像已成功绘制,但当我尝试使用 BufferedImage 绘制它时,情况并非如此,如果您尝试运行该程序,您会注意到这一点。只需创建 Test 对象,构造函数就会完成其余的工作。

提前致谢!

我的代码:

public class Test extends JFrame{

static class ImageLoader {
    public static Image loadImage(String name){
        Image img = null;
        img = Toolkit.getDefaultToolkit().getImage(ImageLoader.class.getResource(name));
        return img;
    }
}

class Panel extends JPanel{

    Image sten;
    BufferedImage bf = new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);

    public Panel(Image sten){
        super();
        this.sten = sten;
        initBF();
    } 

    private void initBF(){
        Graphics2D g = (Graphics2D) bf.createGraphics();
        g.drawImage(sten, 0,0,this);
    }

    public void paintComponent (Graphics g)
    {
        g.drawImage(bf, 100,100,null);
        g.drawImage(sten, 0,0,null);
        repaint();
    } 
}


public Test(){
    setSize(new Dimension(500, 500));
    setEnabled(true);
    this.setBounds(50, 150, 500, 500);
    setVisible(true);

    Image sten = ImageLoader.loadImage("sten.png");;

    Panel panel = new Panel(sten);
    panel.setBackground(Color.GREEN);
    panel.setSize(500, 500);
    this.add(panel);

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    panel.paintComponent(this.getGraphics());
}

}

最佳答案

问题在于 Toolkit.getDefaultToolkit().getImage 异步加载图像,因此在调用 paintComponent 时不会加载图像。使用 MediaTracker 进行阻止,直到图像加载完毕:

public Image loadImage(String name) {
   Image img = null;
   MediaTracker tracker = new MediaTracker(myPanel); // pass the panel from ctor
   img = Toolkit.getDefaultToolkit().getImage(ImageLoader.class.getResource(name));
   tracker.addImage(img, 0);
   try {
      tracker.waitForID(0);
   } catch (InterruptedException e) {
      e.printStackTrace();
   }

   return img;
}

或者简单得多:

img = ImageIO.read(ImageLoader.class.getResource(name)));

这将消除使用 MediaTracker 的需要。

一些注意事项:

  • 不要直接调用paintComponent,而是通过调用repaint来请求重绘。
  • 不要使用 getGraphics 进行自定义绘制 - 这使用 transient Graphics 引用。
  • 使用自定义 Graphics 引用时,请确保在使用完该引用后调用 Graphics#dispose

关于java - 在 BufferedImage 上绘制 Image 对象以供以后使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16736379/

相关文章:

java - 有没有办法在实现方法时包含接口(interface)的名称

python - 如何将文件夹下的所有bytes文件转换为图片

php - 无法使用 PHP 显示数据库中的图像

r - 带 Lattice & panel.bpplot 的垂直箱形百分位图

C# 获取可滚动面板的总内部区域

java - 此正则表达式需要嵌套括号

java - 需要在 for 循环中将变量再次初始化为零

java - 替换java中的通配符

html - 使用响应式设计的图像不显示在 IE 中

java - JFrame 布局多个 JPanel