1

I'm trying to code a program, that reads an Image into a BufferedImage, paint it on the JFrame, paint circles in it, and writes it to a File.

The following code will do all of it except the content of the saved file. The saved image only contains the untouched BufferedImage. No Circles ;) I already treid to figure it out by changing and adding some code, but it didn't help a lot.

public class PaintImage extends Component {

BufferedImage img;
private int pngWidth, pngHeight;

public int getPngWidth() {
    return pngWidth;
}

public int getPngHeight() {
    return pngHeight;
}

public void paint(Graphics g) {
    super.paint(g);

 //g = img.createGraphics();
 g.drawImage(img, 0, 0, 809, 1080, null);
 g.drawOval(33, 33, 444, 444);
}

public PaintImage() {
try {
    img = ImageIO.read(new File("C:\\karte_vorlage.png"));
    pngWidth = img.getWidth();
    pngHeight = img.getHeight();

} catch (IOException e) {
}
}

public void writeImage () {
    try {
     img.getGraphics();
        ImageIO.write(img, "png", new File("C:\\save.png"));
    } catch (IOException e1) {
        e1.printStackTrace();
    }
}


}

Uncommenting g = img.createGraphics(); causes a disorted image.

Please help me. thank you all in advance.

edit: 1. The method paint(Graphics g) is called twice. In case of minimizing it will be called twice again.

Kronos
  • 141
  • 1
  • 11
  • *"..class PaintImage extends Component"* Huh. Where is the Swing part? For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Aug 15 '12 at 09:26
  • I just noticed, that the method "paint(Graphics g)" in this example is called twice. If I minimize and maximize it, it will recalled twice again. Why twice? I added a System.out to recognize it :) – Kronos Aug 15 '12 at 09:29

3 Answers3

2

You could just simple paint the component directly to the BufferedImage

BufferedImage tempImage = new BufferedImage(imagePane.getWidth(), imagePane.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = tempImage.createGraphics();

imagePane.printAll(g);

ImageIO.write(tempImage, "png", new File("C:\\save.png"));

You may want to play around with the width & height to better meet your requirements though

UPDATED

Keep thinking about this.

Another idea would be to create some kind of "paint manager" or "paintable" interface, that given a Graphics content could paint it self (obviously you'd like to know some more info, like width & height)

This would mean that it wouldn't matter where it was painted.

The other thing is you might like to provide hints back to the renderer about how the paintable would like to be painted (something like preferred size)

Just an idea

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Draw the circle to the image in another method. You can call this other method whenever you want to. Then in the paint method you just draw the image to the component and nothing else.

public void paint(Graphics g) {
    super.paint(g);
    g.drawImage(img, 0, 0, 809, 1080, null);
}

public void drawCircle() {
    Graphics g = img.getGraphics();
    g.drawOval(33, 33, 444, 444);
}

You can also remove img.getGraphics(); from the writeImage method, as it is not needed there.

msell
  • 2,168
  • 13
  • 30
  • I forgot to mention, that I want to treat the BufferedImage like a canvas. During the runtime there will be changes, so I might reload the original Image to paint new Circles in it. The Jframe should not be painted directly, but the result (when every circle is painted into the BufferedImage) should be displayed. If the User wants to export it, the program shoul save the BufferedImage in its original size and with the Circles in it. I know that sounds kinda confusing, but I don't know how to describe it in an easy way. plus this is not my native language. :) thank you very much – Kronos Aug 15 '12 at 09:25
  • It seems like 'display/edit an image with circles then save' about sums it up? BTW - please post an SSCCE. – Andrew Thompson Aug 15 '12 at 09:36
  • Sorry but I do not know what to do, to post a SSCCE?! :( – Kronos Aug 15 '12 at 09:46
  • Updated my answer based on your first comment – msell Aug 15 '12 at 10:41
0

You should change your design. Try this way:

  1. read the png file and save it to a bufferedImage.
  2. change your paint() method(this is very important because you want is a new Image with an addtional element, but your code mean to first draw a png and then draw an oval on the UI). it does not modify the bufferedImage. add your own event to change the bufferedImage. For example, when your click a button run a method like this:

void foo(bufferedImage) {

    g = bufferedImage.getGraphis();
    g.drawSomething();
}
public void paint(Graphics g) {
    g.drawImage(bufferedImage);
}
Squall
  • 807
  • 1
  • 6
  • 9