当我说红色时,BufferedImage会绘制出白色

6

我很笨,这可能是一个非常愚蠢的解决方案。

我有这段代码:

BufferedImage bi = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
bi.getGraphics().setColor(Color.red);
bi.getGraphics().fillRect(300, 350, 100, 50);
ImageIO.write(bi, "jpeg", new File("image.jpg"));

我看到一个黑色的800x600矩形和一个白色的矩形在里面。这是为什么呢?
谢谢 :)

3
详细说明MBFG的帖子,每次调用getGraphics时你都会创建一个新的Graphics对象,它们彼此没有关联。相反,按照他的建议创建一个Graphics对象。另外,在完成后不要忘记将其释放。 - Hovercraft Full Of Eels
2个回答

13

每次在 BufferedImage 上调用 getGraphics() 方法都会得到一个新的 Graphics 对象,因此在其中设置颜色不会对下一个对象产生影响。因此请缓存 Graphics 对象。

BufferedImage bi = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
g.setColor(Color.red);
g.fillRect(300, 350, 100, 50);
ImageIO.write(bi, "jpeg", new File("/home/dave/image.jpg"));

1
同意 +1。另外,当使用完 Graphics 对象时,添加调用 dispose 的习惯是很好的。 - Hovercraft Full Of Eels
谢谢!我以为它只返回图像图形对象。 - Rubén
+1 你比我更敏捷,证明了你更加灵活,而我是个大胖子! :-) - trashgod
@trashgod:我想你只会处理你创建的Graphics对象吧?例如从paintComponents传递给你的Graphics对象不应该被处理,对吧? - MeBigFatGuy
@MBFG:是的,我理解了;我会发布一个示例供参考。这里有一个列表列出了这样的方法。 - trashgod

2

作为参考,这里有一个示例,可能对调试图形上下文很有用。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @https://dev59.com/vFbUa4cB1Zd3GeqPBbkj */
public class RedOrWhite extends JPanel {

    private static final int W = 800;
    private static final int H = 600;

    public RedOrWhite() {
        this.setLayout(new GridLayout());
        this.setPreferredSize(new Dimension(W, H));
        int w = W / 2;
        int h = H / 2;
        int r = w / 5;
        BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bi.createGraphics();
        g.setColor(Color.gray);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.blue);
        g.fillRect(w / 2 - r, h / 2 - r / 2, 2 * r, r);
        g.dispose();
        this.add(new JLabel(new ImageIcon(bi), JLabel.CENTER));
    }

    private void display() {
        JFrame f = new JFrame("RedOrWhite");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new RedOrWhite().display();
            }
        });
    }
}

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