# BufferedImage drehen



## SebastianM (15. Aug 2007)

Hallo Leute, ich habe folgendes Problem:

Ich will eine GUI für ein Menü erstellen; die GUI soll hauptsächlich aus drehbaren Elementen bestehen. Man kann sich das evtl. wie einen Lautstärkeregler vorstellen. Zuerst Lade ich dazu ein Bild in ein BufferedImage und drehe es dann mit einem Timer um einen bestimmten Winkel. Das Problem das ich nun habe, ist, dass das Bild bei erneuter Drehung durch den Timer wieder aus der Anfangsposition anfängt. Also wenn ich z.B. erst um 45° drehe und dann nochmals weiter drehen möchte, beginnt leider alles wieder bei 0°. Irgendwie muss ich das Bild also nach der Drehung "einfrieren" oder cachen... 

Hier mal paar Code-Schnippsel:

```
public  BufferedImage getImage() {
		try {			
			 image = ImageIO.read(new File("src/icons/oben4.jpg"));			
			}
			} 
       catch (IOException e)   {
    	   e.printStackTrace();
    	   } 	
       return image;
	}
```


```
private JPanel getPanel()  {
		if (a == null) {
			a = new JPanel();						
			labelA = new JLabel(new ImageIcon(getImage()));
	      		a.add(labelA);	      
	                a.setBounds(0,0,800,800);        
	                a.setVisible(true);
		}
		return a;
	}
```


```
public  static BufferedImage rotation(BufferedImage image, double angle) {
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        GraphicsConfiguration gc = getDefaultConfiguration();
        BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
        Graphics2D g = result.createGraphics();
        g.translate((neww-w)/2, 0/2);
        g.rotate(angle, w/2, h/2);
        g.drawRenderedImage(image, null);
        g.dispose();
        return result;        
    }
```


```
public static GraphicsConfiguration getDefaultConfiguration() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        return gd.getDefaultConfiguration();
    }
```


```
public void startTimer() {
		timer =  new Timer(20, new ActionListener(){
			  double angle = 0;
            public void actionPerformed(ActionEvent evt) {
            	 angle += Math.PI/20;
                 labelA.setIcon(new ImageIcon(rotation(image, angle)));
            	counter++;
            	
	            	if (counter == 10){
	            		timer.stop();
	            	}                 	 
            	}
        		});
		timer.start();
	}
```

bin für jeden tip dankbar!


----------



## para_ (15. Aug 2007)

Das ist weil du am "image" nichts änderst, sondern du ein neues BufferedImage erzeugst ( "result" ) und dieses dann als ImageIcon setzt, du musst "image" direkt verändern, entweder direkt in rotation() oder dann vor dem setzen des ImageIcons in startTimer(): 


```
image = rotation(image, angle);
labelA.setIcon(new ImageIcon(image));
```

Oder du erstellst dir ne variable, sowas wie currentAngle, die du dann immer wenn du rotation aufrufst abänderst.

z.B. wäre currentAngle am anfang 0 (°)
du rufst rotation auf mit einem winkel von 50° -> du drehst das bild um 50°+ currentAngle° (currentAngle ist jetzt 50)
du rufst rotation auf mit einem winkel von -20° -> du drehst das bild um -20° + currentAngle° (currentAngle ist jetzt 30)
usw.


----------



## SebastianM (15. Aug 2007)

danke für die Antwort! habe deine Lösung gerade probiert, allerdings habe ich da das Problem dass mir das Bild während der Drehung nach rechts aus der Bild wandert und ich relativ schnell einen out of memory fehler bekomme!

ciao
Basti


----------



## para_ (15. Aug 2007)

Das hat aber eher was damit zu tun dass du das Bild nicht nur drehst sondern auch noch verschiebst und da dann wohl dein Fehler auftritt. Ist bestimmt was bei der Berechnung nich so ganz richtig..

Allein durch die Änderung des Winkels läuft dir das Bild nämlich nicht so einfach weg.^^


----------

