This discussion is archived
5 Replies Latest reply: May 3, 2011 2:01 PM by morgalr RSS

Graphics to BufferedImage ?

858876 Newbie
Currently Being Moderated
Hello there.

Ill try to explain this the simplest way possible. Lets say i have a map, and sprites on that map. The map by itself its static, it will only move along as a camera move. Im calling, methods directly in Paint from my applet to draw the map, and draw the sprites. What i am willing to do it, Drawing the map into a separate Graphics or a BufferedImage, so i can draw the map on the final graphics. This would also make i draw the map only once, witch would be good as well, cause actually map drawing is on a loop.
Thanx in advance for any help.

[]´s Gabriel
  • 1. Re: Graphics to BufferedImage ?
    gimbal2 Guru
    Currently Being Moderated
    A bit confusing post. But going by your title, you want to create a BufferedImage, draw to that and then draw that BufferedImage to the window. Right?

    Creating a BufferedImage can be done through its constructor. All you need to know is the width and height in pixels, plus if you want it to be transparent or not (TYPE_INT_RGB or TYPE_INT_ARGB).

    Drawing to a BufferedImage is done by obtaining a Graphics2D instance for it, through BufferedImage.createGraphics(). Don't forget to dispose() that Graphics object when you're done with it.



    Note: is there a specific reason why you want to do this? Swing is by default double buffered, so without knowing it you are already drawing to an offscreen buffer in stead of directly to the screen.
  • 2. Re: Graphics to BufferedImage ?
    858876 Newbie
    Currently Being Moderated
    Sorry for the confusing post.

    I have a map, and i have sprites, and a window class. Each is drawd by a different class. My Paint method is something similar to this:
    public void paint(Graphics g) {
    
       MapClass.drawMap(g);
       SpriteClass.drawSprites(g);
       WindowClass.drawWindows(g);
       
    }
    now, this makes me draw the map on the game loop, and if i wanted to move the map around i would have to translate the graphics to move only the map and sprites. However, i belive this could be easyer if i have a separate map for example, and i could use my paint method like this:
    public void paint(Graphics g) {
    
       g.drawImage(MapClass.getMap(), camX, camY, screenX, screenY);
    
       g.drawImage(SpriteClass.getSprites(),  camX, camY, screenX, screenY);
      
       WindowClass.drawWindows(g);
       
    }
    So i could control camera movements easy, and i can save the map into memory so i dont have to draw it over and over again. Ive googled into how to create a buffered image from a graphics but couldnt do it. Lets say i have this method doing the paint ( a simple one )
    // class Sprites
    public void drawSprites(Graphics g) {
    
        g.drawImage( sprite, spriteX, spriteY, sizeX, sizeY);
    
    }
    Now, i would have something like that
    public BufferedImage getSprites() {
       Graphics g = new Graphics();
       g.drawImage( sprite, spriteX, spriteY, sizeX, sizeY);
       BufferedImage img = new BufferedImage(parms, parms2);
       img = g; // ? 
       return img;
    }
    So i could just paint this img on the main graphics, and move it easy, and pheraphs store it in memory.

    Tryed to explain it easyer. Thanx for your help. =]
  • 3. Re: Graphics to BufferedImage ?
    morgalr Explorer
    Currently Being Moderated
    Ziden,

    It's really easy to do, if you notice your paint takes a reference to a graphics context as an argument, you basically make a new method that takes a graphics context as the arguemnt and pass it the graphis context to a BufferedImage. In that method copy all of the commands that are now in your class' overridden paint, then make a timer object that when fired, will update your image. It works very well in SWING when using paintComponent because SWING has double buffering as default.
    public void paint(Graphics g) {  //copy this to another method
       MapClass.drawMap(g);
       SpriteClass.drawSprites(g);
       WindowClass.drawWindows(g);
    }
    New Method
    public void MyOffScreenPaint(Graphics g) { 
       MapClass.drawMap(g);
       SpriteClass.drawSprites(g);
       WindowClass.drawWindows(g);
    }
    public void paint(Graphics g) {  //new override for class paint--note MyImage is the same image you used the graphics context from MyOffScreenPaint
       super.paint(g);
       g.drawImage(MyImage, 0, 0, this);
    }
    Now you just need an event handler that will call your MyOffScreenPaint with the graphics context from MyImage.
  • 4. Re: Graphics to BufferedImage ?
    858876 Newbie
    Currently Being Moderated
    i didnt got how i could get MyImage
    im sorry

    this way , as i understood, would be the same then adding a g.drawImage after the call of those 3 draw methods, no ?

    if no, i didnt understood, sorry
  • 5. Re: Graphics to BufferedImage ?
    morgalr Explorer
    Currently Being Moderated
    Here is an example:
    import java.awt.image.BufferedImage;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Junk{
      public Junk(){
        try{
          JFrame f = new JFrame("Offscreen Paint");
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          MyJPanel p = new MyJPanel();
          f.add(p);
          f.pack();
          f.setVisible(true);
        }catch(Exception e){
          e.printStackTrace();
        }
      }
      public static void main(String[] args){
        new Junk();
      }
      class MyJPanel extends JPanel implements ActionListener{
        int inc = 1;
        int count = 0;
        BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
        Graphics myG = bi.createGraphics();
        Timer t = new Timer(500, this);
        public MyJPanel(){
          this.setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight()));
          myG.clearRect(0, 0, 256, 256);
          this.repaint();
          t.start();
        }
        public void actionPerformed(ActionEvent e){
          MyPaintOffScreen(myG);
          this.repaint();
        }
        public void paintComponent(Graphics g){
          super.paintComponent(g);
          g.drawImage(bi, 0, 0, this);
        }
        public void MyPaintOffScreen(Graphics g){
          if(count<0){
            count = 1;
            inc *= -1;
          }else if(count > 9){
            count = 8;
            inc *= -1;
          }
          g.clearRect(0, 0, 256, 256);
          g.drawString(Integer.toString(count), 128, 128);
          count+=inc;
        }
      }
    }

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points