Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 7 of 7

Thread: XOR'ing BufferedImages onto a Graphics2D object

  1. #1
    Junior Member
    Join Date
    Oct 2010
    Posts
    14
    Thanks
    2
    Thanked 2 Times in 1 Post

    Default XOR'ing BufferedImages onto a Graphics2D object

    i've begun programming a game in java, and was wondering how one would XOR a sprite onto a Graphics2D object. i know about Graphics2D's setXORMode() method, but i'm unsure how to apply it correctly.
    if you aren't sure what XOR logic is for displaying sprites, here is a good link to show a graphical example. the images are in black and white, but the concept applies to colored images as well.


  2. #2
    Member Darryl.Burke's Avatar
    Join Date
    Mar 2010
    Location
    Madgaon, Goa, India
    Posts
    489
    Thanks
    8
    Thanked 45 Times in 43 Posts

    Default Re: XOR'ing BufferedImages onto a Graphics2D object

    i know about Graphics2D's setXORMode() method, but i'm unsure how to apply it correctly.
    What have you tried? It's a two-liner to use that mode: set the color, then set the XOR color.

    To get better help sooner, post a SSCCE (Short, Self Contained, Compilable and Executable) example that demonstrates the problem.

    db

  3. #3
    Junior Member
    Join Date
    Oct 2010
    Posts
    14
    Thanks
    2
    Thanked 2 Times in 1 Post

    Post Re: XOR'ing BufferedImages onto a Graphics2D object

    i tried to make it short but it still ended up relatively long.. here's the code:

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import javax.swing.*;
    import java.io.File;
    import javax.imageio.ImageIO;
     
     
    public class Example extends JFrame{
    	MyPanel panel;
    	BufferedImage bg, sprite;
     
    	public static void main(String[] args){
    		new Example();
    	}
     
    	public Example(){
    		mainLoop();
    	}
     
    	public void mainLoop(){
    		try{
    		bg = 	ImageIO.read(new File("")); // your file
    		sprite =  ImageIO.read(new File("")); // your file
    		}
    		catch(java.io.IOException e){
    			e.printStackTrace();
    		}
    		JFrame frame = new JFrame();
    		frame.setSize(200,200);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		panel = new MyPanel(bg, sprite);
    		frame.getContentPane().add(panel);
    		panel.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"),"moveRight");
    		panel.getActionMap().put("moveRight",moveRight);
    		frame.setVisible(true);
    		while(true){
    			panel.updateScreen();
    		}
    	}
     
    	Action moveRight = new AbstractAction() {
        	public void actionPerformed(ActionEvent e) {
            panel.xPos += 3;
        	}
    	};
    }
     
    class MyPanel extends JPanel{
    	BufferedImage buffer = new BufferedImage(200,200,BufferedImage.TYPE_4BYTE_ABGR);
    	Graphics2D g2d;
    	BufferedImage sprite;
    	int xPos = 0;
     
    	public MyPanel(BufferedImage bg,BufferedImage sp){
    		g2d = buffer.createGraphics();
    		g2d.drawImage(bg,null,0,0);
    		sprite = sp;
    	}
           // issue lies here.
    	public void updateScreen(){
    		Graphics2D screen = (Graphics2D) this.getGraphics();
    		g2d.setXORMode(Color.WHITE);		            			
    		g2d.drawImage(sprite,null,xPos,30);
    		screen.drawImage(buffer,null,0,0);
    		g2d.drawImage(sprite,null,xPos,30);
    	}
    }

    if you take out g2d.setXORMode(Color.WHITE); , the program runs as expected. the sprite bufferedimage moves across the screen if you hold down the right arrow key.

    however, it leaves image debris. i know that i could have my method draw the background, and then draw the sprite every frame, but that is slow. what i am trying to do is use XORMode so that you draw the sprite to the buffer, display the buffer (so the user sees the sprite), and then XOR the sprite again, leaving the buffer as just the background.

    edit: and i just noticed i had Example implement JFrame but made a JFrame object in the class anyway.. ignore that and the many other flaws. this was written at around 1 in the morning.
    Last edited by nemo; November 14th, 2010 at 12:50 AM.

  4. #4
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,267
    Thanks
    176
    Thanked 821 Times in 764 Posts
    Blog Entries
    5

    Default Re: XOR'ing BufferedImages onto a Graphics2D object

    First, I would highly recommend doing all your painting using the paintComponent method, and not have your own infinite 'mainLoop'. The EDT takes care of all of this for you and then some. If you need to redraw for animation, use a SwingTimer. Changing your code to using the EDT should take care of the immediate problem of sprite 'trails'.

  5. #5
    Member Darryl.Burke's Avatar
    Join Date
    Mar 2010
    Location
    Madgaon, Goa, India
    Posts
    489
    Thanks
    8
    Thanked 45 Times in 43 Posts

    Default Re: XOR'ing BufferedImages onto a Graphics2D object

    Never never never use getGraphics() of a Component. Recommended reading, in line with copeg's recommendation:
    Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    Don't forget to invoke the super implemetation at the head otf the paintComponent override, unless your custom painting fills the entire area with non-transparent pixels.

    db

  6. #6
    Junior Member
    Join Date
    Oct 2010
    Posts
    14
    Thanks
    2
    Thanked 2 Times in 1 Post

    Default Re: XOR'ing BufferedImages onto a Graphics2D object

    Quote Originally Posted by Darryl.Burke View Post
    Never never never use getGraphics() of a Component. Recommended reading, in line with copeg's recommendation:
    Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI With JFC/Swing)

    Don't forget to invoke the super implemetation at the head otf the paintComponent override, unless your custom painting fills the entire area with non-transparent pixels.

    db
    why not? i had it working using paintComponent, but it was at least 5 times slower than using a buffer. plus, if i need to, i can using a SwingTimer to control the painting of the screen manually. basically, what's the advantage of an EDT over manually creating a buffer? and lastly, can anyone answer my original question, how to use XORMode when dealing with moving sprites?

  7. #7
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,267
    Thanks
    176
    Thanked 821 Times in 764 Posts
    Blog Entries
    5

    Default Re: XOR'ing BufferedImages onto a Graphics2D object

    Quote Originally Posted by nemo View Post
    why not?
    Because you don't know what state the Graphics component is in, and accessing it from a different thread (eg the main thread as opposed the EDT thread) makes matters much worse. Things like window resizes, events, and/or layouts can change the graphics object. Meaning it can get wiped out, transformed, or worse set to null while you are trying to access it, resulting in unexpected behavior. And when I say unexpected I mean unexpected - it may work now but down the line you never know. Using paintComponent ensures you will paint to a Graphics object with the expected behavior.

    i had it working using paintComponent, but it was at least 5 times slower than using a buffer. plus, if i need to, i can using a SwingTimer to control the painting of the screen manually.
    If its that much slower that it is noticeable to a human, you should profile the code and fix the bottleneck. Things you are doing should be lightning fast, and if they are not there are always ways to fix it and speed it up.

    basically, what's the advantage of an EDT over manually creating a buffer?
    No unexpected behavior I mentioned above, Listeners (ActionListener, MousetListener, KeyListener, etc...) already managed for you, more assurance the code is portable..are just a few. And you aren't manually creating a buffer, you are retrieving the one created for you by Swing in the EDT.
    and lastly, can anyone answer my original question, how to use XORMode when dealing with moving sprites?
    I haven't played with this option for some time, so shouldn't lead you astray with my assumptions.
    Last edited by copeg; November 14th, 2010 at 02:38 PM.

Similar Threads

  1. question about transforming Graphics2D
    By gib65 in forum AWT / Java Swing
    Replies: 1
    Last Post: October 7th, 2010, 09:53 PM
  2. java graphics2d issue
    By nana-j13 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: September 15th, 2010, 03:49 PM
  3. 2D Object makes my object smaller, Why?
    By MassiveResponse in forum What's Wrong With My Code?
    Replies: 2
    Last Post: May 15th, 2010, 02:33 PM
  4. Help with object
    By Spangle1187 in forum Collections and Generics
    Replies: 3
    Last Post: April 22nd, 2010, 04:34 PM
  5. Replies: 1
    Last Post: November 14th, 2008, 02:00 PM