6

It must be a very stupid solution but I'm blind.

I have this code:

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"));

And I get this black 800x600 rectangle and a WHITE rectangle in it. Why is this?

Thanks :)

Rubén
  • 524
  • 5
  • 22
  • 3
    To elaborate on MBFG's post, you're creating a new Graphics object with each call to getGraphics, both unrelated to each other. Do what he recommends instead and create one Graphics object. Also, don't forget to dispose it when you're done. – Hovercraft Full Of Eels Apr 30 '11 at 17:33

2 Answers2

13

Each time you call getGraphics() on a BufferedImage you get a new Graphics object, so setting the color on one, doesn't set it on the next one. So cache the graphics object.

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"));
MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
  • 1
    Agree 1+. Also it's good habit to add call to dispose on the Graphics object when done with it. – Hovercraft Full Of Eels Apr 30 '11 at 17:35
  • Thanks! I was assumming it was only returning the Image graphics object – Rubén Apr 30 '11 at 17:35
  • +1 You beat me to it, proving that you are more agile and _I_ am the bigger fat guy! :-) – trashgod Apr 30 '11 at 17:38
  • @trashgod: i suppose you only dispose() of Graphics objects you create? for instance the graphics object passed to you from paintComponents shouldn't be disposed i'd think, right? – MeBigFatGuy Apr 30 '11 at 23:57
  • @MBFG: Yes, that's my understanding; I'll post the example for reference. Here's a [list](http://stackoverflow.com/questions/2486136/what-method-in-java-is-used-to-destroy-your-objects/2486200#2486200) of such methods. – trashgod May 01 '11 at 02:32
2

For reference, here's an example that might be handy for tinkering with a graphics context.

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;

/** @http://stackoverflow.com/questions/5843426 */
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();
            }
        });
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045