14 Replies - 2656 Views - Last Post: 29 May 2011 - 11:33 AM Rate Topic: -----

#1 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Rotating a BufferedImage

Posted 28 May 2011 - 01:22 PM

Hey all, I am really at a lost as to how to rotate my image by X degrees, I managed to rotate my image by X radians using:
       Graphics2D g2d=(Graphics2D)g
         g2d.translate(150, 0); 
         g2d.rotate(1);  // Rotate the image by 1 radian.
         g2d.drawImage(image, 0, 0, 100, 100, this);


However I am at a loss as for how to rotate an image dependant on where my mouse is at.
For example, I use this:
//instance variables declared above
                xpos = (m.getXOnScreen()-5);
	                ypos = (m.getYOnScreen()-50);


to get the position of the mouse on the screen but I am unsure as to how to work out an angle for this value, I have thought of maybe using cosine rule:
c = square route(xpos^2+ypos^2-cos(xpos*ypos*cos(C))


to no avail, if anyone could point me in the right direction as to how I could rotate the BufferedImage by X degrees, even just a general method or some pseudo-code that I could then try to implement it would be greatly appreciated.

tl;dr: I am stuck mainly because I cannot figure out as to how one would get an angle between two co-ordinates on the monitor :/
Are there any libraries that can do this calculation for me or must I continue trying to figure it out?
Thanks,
v0rtex

Is This A Good Question/Topic? 0
  • +

Replies To: Rotating a BufferedImage

#2 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 28 May 2011 - 02:01 PM

Ok, I have found a function for Image (not BufferedImage) called rotate that can rotate the image by X degrees like so:
	public void rotateImage(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.rotate(45);
	     g2d.drawImage(playerImage, 60,60 , this);
	}


However my image comes out to the Far Left of the JPanel, any ideas?
Was This Post Helpful? 0
  • +
  • -

#3 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 559
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Rotating a BufferedImage

Posted 28 May 2011 - 02:12 PM

You mean it comes out to that position after your rotation? I am lame at maths, but I would imagine this is happening due to the point it is rotating from. Try using the other rotate method
public abstract void rotate(double theta,
double x,
double y)

Concatenates the current Graphics2D Transform with a translated rotation transform. Subsequent rendering is transformed by a transform which is constructed by translating to the specified location, rotating by the specified radians, and translating back by the same amount as the original translation. This is equivalent to the following sequence of calls:

translate(x, y);
rotate(theta);
translate(-x, -y);

Once again, I dont know much about maths, but it sounds like it should fix your problem.
Was This Post Helpful? 0
  • +
  • -

#4 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 28 May 2011 - 02:24 PM

Sadly the image is still not in the middle. I was thinking is there a way for me to simply update my Image playerImage?
Was This Post Helpful? 0
  • +
  • -

#5 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 559
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Rotating a BufferedImage

Posted 28 May 2011 - 02:55 PM

I think this is more a question for people good at maths, that doesnt include me!!!. I dont know what updating the image will do, but generally to update it, you would just call repaint().
Was This Post Helpful? 0
  • +
  • -

#6 nick2price  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 559
  • View blog
  • Posts: 2,826
  • Joined: 23-November 07

Re: Rotating a BufferedImage

Posted 28 May 2011 - 03:02 PM

Found some code for you to ponder over
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;

import javax.swing.JFrame;

/**
 * RotateImage45Degrees.java - 1. scales an image's dimensions by a factor of
 * two 2. rotates it 45 degrees around the image center 3. displays the
 * processed image
 */
public class RotateImage45Degrees extends JFrame {
  private Image inputImage;

  private BufferedImage sourceBI;

  private BufferedImage destinationBI = null;

  private Insets frameInsets;

  private boolean sizeSet = false;

  public RotateImage45Degrees(String imageFile) {
    addNotify();
    frameInsets = getInsets();
    inputImage = Toolkit.getDefaultToolkit().getImage(imageFile);

    MediaTracker mt = new MediaTracker(this);
    mt.addImage(inputImage, 0);
    try {
      mt.waitForID(0);
    } catch (InterruptedException ie) {
    }

    sourceBI = new BufferedImage(inputImage.getWidth(null), inputImage
        .getHeight(null), BufferedImage.TYPE_INT_ARGB);

    Graphics2D g = (Graphics2D) sourceBI.getGraphics();
    g.drawImage(inputImage, 0, 0, null);

    AffineTransform at = new AffineTransform();

    // scale image
    at.scale(2.0, 2.0);

    // rotate 45 degrees around image center
    at.rotate(45.0 * Math.PI / 180.0, sourceBI.getWidth() / 2.0, sourceBI
        .getHeight() / 2.0);

    /*
     * translate to make sure the rotation doesn't cut off any image data
     */
    AffineTransform translationTransform;
    translationTransform = findTranslation(at, sourceBI);
    at.preConcatenate(translationTransform);

    // instantiate and apply affine transformation filter
    BufferedImageOp bio;
    bio = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

    destinationBI = bio.filter(sourceBI, null);

    int frameInsetsHorizontal = frameInsets.right + frameInsets.left;
    int frameInsetsVertical = frameInsets.top + frameInsets.bottom;
    setSize(destinationBI.getWidth() + frameInsetsHorizontal, destinationBI
        .getHeight()
        + frameInsetsVertical);
    show();
  }

  /*
   * find proper translations to keep rotated image correctly displayed
   */
  private AffineTransform findTranslation(AffineTransform at, BufferedImage bi) {
    Point2D p2din, p2dout;

    p2din = new Point2D.Double(0.0, 0.0);
    p2dout = at.transform(p2din, null);
    double ytrans = p2dout.getY();

    p2din = new Point2D.Double(0, bi.getHeight());
    p2dout = at.transform(p2din, null);
    double xtrans = p2dout.getX();

    AffineTransform tat = new AffineTransform();
    tat.translate(-xtrans, -ytrans);
    return tat;
  }

  public void paint(Graphics g) {
    if (destinationBI != null)
      g.drawImage(destinationBI, frameInsets.left, frameInsets.top, this);
  }

  public static void main(String[] args) {
    new RotateImage45Degrees("fruits.png");
  }

}

Was This Post Helpful? 2
  • +
  • -

#7 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 991
  • Posts: 2,200
  • Joined: 05-April 11

Re: Rotating a BufferedImage

Posted 28 May 2011 - 03:08 PM

View Postv0rtex, on 28 May 2011 - 02:01 PM, said:

Ok, I have found a function for Image (not BufferedImage) called rotate that can rotate the image by X degrees like so:
	public void rotateImage(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.rotate(45);
	     g2d.drawImage(playerImage, 60,60 , this);
	}


However my image comes out to the Far Left of the JPanel, any ideas?


Try and look up rotate(double theta, double x, double y).

Also BufferedImage extends Image so BufferedImage is also an Image :)
Was This Post Helpful? 0
  • +
  • -

#8 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 29 May 2011 - 01:38 AM

Okay so the image itself is rotating correctly however the painting of the image causes lag? Any ideas?
Here is the code:

Panel.java


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
public class Panel extends JPanel{

	public boolean alwaysDraw = true;
	public static final int WIDTH = 800;
	public static final int HEIGHT = 600;
	public int ypos = 0;
	public int xpos = 0;
	Panel pane; //make a panel class available throughout class
   Image playerImage;
 

	Panel () {
		setSize(WIDTH, HEIGHT);
		//load images routine:
		ImageIcon playerIMGICON = new ImageIcon("player.png");
		if (playerIMGICON == null) {
			System.exit(0);
		}
	    playerImage = playerIMGICON.getImage();
	    prepareImage(playerImage,this);
	
		 //-------
		 //setup mouse for input
		   addMouseListener(new MouseHandler(this));
		   new Timer(200, updateTimer).start(); //start timer
	
	}
	
	Action updateTimer = new AbstractAction() { //Swing Timer
	    public void actionPerformed(ActionEvent e) {
	  
	    	if (alwaysDraw) {
	    /* //to check if SwingTimer is working correctly:
	    			String st="Welcome";
	    		JOptionPane.showMessageDialog(null,st);
	    		*/
		    repaint();
	    	}
	    }
	};

	

	public void rotatePlayer(Graphics g) {	
		//Centre = width = 800/2, height = 600/2
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D)g;	
		int curxpos = MouseInfo.getPointerInfo().getLocation().x- 5;
		int curypos = MouseInfo.getPointerInfo().getLocation().y -50; 
		//that is in my mouseHandler
		double o =  400-curypos  ;

		double a = curxpos - 400 ; 
	
		double angle = Math.toRadians(getAngle(o,a));
g2d.setPaint(Color.blue); //to see what is rotating

		 g2d.rotate(angle, 400, 300);
		g2d.drawImage(playerImage, 300, 200, this);
		//g2d.draw(new Line2D.Double(curxpos, curypos, 400, 300));


	}



	 public double getAngle(double a, double o){
		  	
		    double rat = o/a;
		    double ang = Math.atan(rat);
		    double rAng = Math.toDegrees(ang);
		    if( a < 0){
		    	rAng += 180;
		    }
		    if(o < 0 && a > 0){
		    	rAng += 360;
		   }
		    
		  
		  return rAng;
		  
	  }
	  
		    
		  
	

	public void paintImages(Graphics g) {
		 Graphics2D g2d = (Graphics2D)g;
	     g2d.drawImage(playerImage, WIDTH/3, HEIGHT/3, this); //paint @ center 	
	}
	
	
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
        // paintImages(g);
       rotatePlayer(g);
     //  shoot(g);
	
	setVisible(true);
}

	  class MouseHandler implements MouseListener { //Listener for mouse input implements MouseListener interface
	        //An interface is a class whereby, code can be setup in the method that calls it however as you will see
	        //by the blank methods, all the methods must be called.

	        public MouseHandler(Panel panel) {
	            pane = panel;
	            
	        }

	        public void mouseClicked(MouseEvent m) {
	         
	      

	        }
	            public void mousePressed(MouseEvent m) { //blank methods that must be overriden for the interface to be implemented without an error
	            
	            }

	            public void mouseReleased(MouseEvent m) {
	            }

	            public void mouseEntered(MouseEvent m) {
	            }

	            public void mouseExited(MouseEvent m) {
	               
	            }
	            public void mouseDragged(MouseEvent m) {
	            
	            }
	        }
}



And the Game.java:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Game extends JFrame{
	public JLabel health = new JLabel("Health = 0 |" );
	public JLabel scoreAndTime = new JLabel(" Score: 0 | Time: 0.00");
	public int playerHealth = 0;
	public int enemyHealth = 0;
	public int score = 0;
	public double time = 0.00;
	Panel panel;
	Game() {
		super("Last Stand");		
panel = new Panel();
setSize(800,600);
//just working with JPanel atm
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(panel);

setVisible(true);
	}
	public static void main(String[] args) {
		new Game();
	}
}


http://img24.imagesh...i/playerar.png/

This post has been edited by v0rtex: 29 May 2011 - 02:10 AM

Was This Post Helpful? 0
  • +
  • -

#9 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 29 May 2011 - 02:15 AM

Nevermind, calling repaint() in rotatePlayer() fixed it :)
Was This Post Helpful? 0
  • +
  • -

#10 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 9026
  • View blog
  • Posts: 33,471
  • Joined: 27-December 08

Re: Rotating a BufferedImage

Posted 29 May 2011 - 09:54 AM

Also, why are you invoking super.paintComponent() in your rotatePlayer() method? If your paintComponent() method invokes rotatePlayer() and super.paintComponent(), you shouldn't be repainting or invoking super.paintComponent in rotatePlayer().
Was This Post Helpful? 1
  • +
  • -

#11 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 29 May 2011 - 10:38 AM

@ macosxnerd101: I do not need it in paintComponent() you are right but I am using it to clear old images/lines when rotating the player in the rotatePlayer() method above.

Also, just one last question, I am trying to make it so that when the user clicks, it draws a line from the image to the point the user clicked however the line itself is a few pixels off where I click, any ideas?

My mousePressed event method is here:
	            public void mousePressed(MouseEvent m) { //blank methods that must be overriden for the interface to be implemented without an error
	            	Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
	            
	            	
	                 xpos = mouseLocation.x;
	            
	                            ypos = mouseLocation.y;
	            }



And the painting of the image is here:
	  public void paintBullet(Graphics g){
		
		  Graphics2D g2d = (Graphics2D)g;
		  g2d.setPaint(Color.blue);
		  
		  g2d.draw(new Line2D.Double(400,300, xpos, ypos));
		
		  
	  }
		  


Thanks,
v0rtex
Was This Post Helpful? 0
  • +
  • -

#12 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 991
  • Posts: 2,200
  • Joined: 05-April 11

Re: Rotating a BufferedImage

Posted 29 May 2011 - 11:03 AM

Point mouseLocation = MouseInfo.getPointerInfo().getLocation();


why are you doing this instead of m.getPoint(); or m.getX() m.getY()
Was This Post Helpful? 0
  • +
  • -

#13 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 29 May 2011 - 11:19 AM

Got the idea from a code snippet on DIC, apparently its meant to get the point on the screen and not relative to an observer. If you have another method that would work (mine is not working), then please suggest it or point me in the right direction.
Was This Post Helpful? 0
  • +
  • -

#14 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 991
  • Posts: 2,200
  • Joined: 05-April 11

Re: Rotating a BufferedImage

Posted 29 May 2011 - 11:30 AM

View Postv0rtex, on 29 May 2011 - 11:19 AM, said:

Got the idea from a code snippet on DIC, apparently its meant to get the point on the screen and not relative to an observer. If you have another method that would work (mine is not working), then please suggest it or point me in the right direction.


Have you found out what the new x and y is for the image you rotate? or have you made so it still has the same x and y as before?
Was This Post Helpful? 0
  • +
  • -

#15 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 218
  • View blog
  • Posts: 758
  • Joined: 02-June 10

Re: Rotating a BufferedImage

Posted 29 May 2011 - 11:33 AM

I tried:
            public void mousePressed(MouseEvent m) { //blank methods that must be overriden for the interface to be implemented without an error
	            //	Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
	            
	            	
	                 xpos = m.getX();
	            
	                            ypos = m.getY();
	            }


to no avail :/

I used an instance variable for the xpos and ypos of the line, these values are then collected when the user presses on the JPanel (hence they are updated), I then attempt to draw a line to those values from the center of my image (which is @ 400,300) to the point that the mouse was:
 g2d.draw(new Line2D.Double(400,300, xpos, ypos));


I am unsure if there is something wrong with how I am drawing, if I am not taking the angle into account properly or if my method in general for the painting is flawed.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1