# Bild drehen



## Benzol (6. März 2006)

Ich habe jetzt schon zeihmlich viel darüber gelesen und mir auch eine eigene Funktion gebastelt. Mir scheint aber, das ich da irgentwo einen Wurm drinne habe. Wird wohl daher eher ein logischer Fehler sein 

Ich habe ein BufferedImage, in dem mein orginalbild verkleinert reingezeichnet wird. Dieses BuffImg möchte ich jetzt dannach in 90° Grad Schritten rotieren.

Dazu habe ich mir eine Funktion geschrieben, die ein BuffImg annimmt, ein neues BuffImg mit vertauschter Breite/Höhe erstellt, und das angenommene per AffineTransform rotiert in das neue einträgt. Danach wird das neue BuffImg zurückgegeben sodass ich es abspeichern kann. Nur leider bekomme ich immer Schwarze Bilder... :suspekt: 
Hier mal ein wenig Code...


```
public BufferedImage RotatePicture(BufferedImage scaledImage, int width, int height)
    {
        AffineTransform trans = AffineTransform.getRotateInstance(90);
        BufferedImage dest = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB);
        
        Graphics2D g = dest.createGraphics();
        g.drawImage(dest, trans, null);
        g.dispose();
        
        return dest;
    }
```


----------



## Thomas Darimont (6. März 2006)

Hallo!

Schau mal hier:

```
/**
 * 
 */
package de.tutorials;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

/**
 * @author Tom
 * 
 */
public class ImageRotatorExample {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        BufferedImage image = ImageIO.read(new File("c:/Winter_big.jpg"));
        BufferedImage rotatedImage = rotateImage(image, 90.0);
        ImageIO.write(rotatedImage, "jpeg", new File("c:/Winter_big_rot.jpg"));
    }

    private static BufferedImage rotateImage(BufferedImage src, double degrees) {
        AffineTransform affineTransform = AffineTransform.getRotateInstance(
                Math.toRadians(degrees),
                src.getWidth() / 2,
                src.getHeight() / 2);
        BufferedImage rotatedImage = new BufferedImage(src.getWidth(), src
                .getHeight(), src.getType());
        Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
        g.setTransform(affineTransform);
        g.drawImage(src, 0, 0, null);
        return rotatedImage;
    }
}
```

Gruss Tom


----------



## Benzol (6. März 2006)

Ich versuche nun schon seit einer Stunde dahinter zu kommen, warum er bei mir das Bild nicht genau dort platziert, wo es hingehört  

Es liegt ja an den letzten Beiden Werten am Ende Zeile

```
AffineTransform affineTransform = AffineTransform.getRotateInstance(Math.toRadians(degrees),src.getWidth()/2, src.getHeight()/2);
```

Ich verstehe aber nicht, was diese Werte angeben und warum sich das Bild so verändert, wie es sich verändert, wenn ich die Werte ändere.  Kannst du mir folgen?


----------



## Thomas Darimont (6. März 2006)

Hallo!

Diese x,y-Koordinaten geben den Drehpunkt an 

Gruss Tom


----------



## Benzol (6. März 2006)

Hmm, das erklärt doch aber noch nicht so richtig, warum das Bild so verschoben ist, oder doch?

EDIT:
Ja ist klar   Ich habe nichts gesagt... nur ist es doch eigentlich logisch, das Bild im Mittelpunkt zu drehen. Nur warum verschiebt sich das Bild? Muss an der Berechnung noch was geändert werden? Du hast doch dein Beispiel bestimmt getestet... da hat es doch funktioniert. Ich habe es quasi 1 zu 1 übernommen....


----------



## Benzol (8. März 2006)

Hat den keiner eine Idee?  Ich komme mit diesem Problem einfach nicht weiter. Habe jetzt schon diverese Berechnungen und Werte ausprobiert... verstehe aber nicht, warum das Bild nicht mittig angezeigt wird.


----------



## klaus-philip (22. August 2006)

Hallo,
hatte anfangs auch die hässlichen schwarzen Streifen. HAbe dann den Quelltext von Thomas ein wenig aufgebohrt. 
Hier ist der Code:


```
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.AffineTransformOp;
import javax.imageio.ImageIO;

public class RotateImage{

 public static int RotAngle = 0;
 
   public RotateImage( int rotate){
      RotAngle =  rotate;
   }

  public static BufferedImage rotateImage(BufferedImage inputImage) {

    int X,Y = 0;
    
    if ((RotAngle == 0)||(RotAngle == 180)||(RotAngle == 360)){
     X = inputImage.getWidth(null);
     Y = inputImage.getHeight(null);
    }else{
     X = inputImage.getHeight(null);
     Y = inputImage.getWidth(null);
    }

    BufferedImage sourceBI = new BufferedImage(X, Y, BufferedImage.TYPE_INT_RGB);

    AffineTransform at = new AffineTransform();

    // rotate around image center
    at.rotate(Math.toRadians( RotAngle ), (sourceBI.getWidth() / 2), (sourceBI.getHeight() / 2) );

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


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


    return sourceBI;
  }

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

    AffineTransform tat = new AffineTransform();
    
    if(RotAngle == 180){
      p2din = new Point2D.Double(0, bi.getHeight());
    }else{
      p2din = new Point2D.Double(0.0, 0.0);
    }
    
    p2dout = at.transform(p2din, null);

    if(RotAngle == 270){
      xtrans = p2dout.getX();
      ytrans = xtrans;
    }else{
      ytrans = p2dout.getY();
      xtrans = ytrans;
    }

    //System.out.println("X: "+ (xtrans) +" Y: "+ (ytrans));

    tat.translate(-xtrans, -ytrans);

    return tat;
  }

  public static void main(String[] args)throws Exception {
    BufferedImage inputImage = ImageIO.read(new File( "xyz.jpg" )); 
    new RotateImage( 90 ); // current Angle
    BufferedImage rotatedImage = rotateImage(inputImage);
    ImageIO.write(rotatedImage , "jpeg", new File("xyz.jpg"));
  }

}
```

Viel Spass damit


----------



## Bäästy (16. Dezember 2007)

ich bin am verzweifeln:
ich möchte ein gedrehtes bild in einem applet ausgeben
und zwar mit der mouseMove-Methode

ich probiere da sein ein paar tagen ständig rum und mein letzter stand ist folgender:
	
	
	



```
package shoter;
import java.applet.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;




public class Shoter extends Applet {

	Font f = new Font("TimesRoman", Font.BOLD,36);
	String img_left="pic/left.jpg",img_right="pic/right.jpg";
	BufferedImage img_l,img_r;


	Graphics g ; 

	public void init(){
		g=getGraphics();
	}
	
    public static void main(String file)  {
     
    }
    
    private static BufferedImage rotateImage(BufferedImage src, double degrees) {

        AffineTransform affineTransform = AffineTransform.getRotateInstance(
                Math.toRadians(degrees),
                src.getWidth() / 2,
                src.getHeight() / 2);
        BufferedImage rotatedImage = new BufferedImage(src.getWidth(), src
                .getHeight(), src.getType());
        Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
        g.setTransform(affineTransform);
        g.drawImage(src, 0, 0, null);
        return rotatedImage;
    }
	
    public void paint(Graphics g){
	
		g.setFont(f);
		g.setColor(Color.black);
		g.drawString("BDU-Shoter!!",250,50);
	}
	
    public static BufferedImage img (String src)throws IOException{
    	Image ImG= new ImageIcon(ImageIO.read(new File(src))).getImage();
    	BufferedImage img=(BufferedImage)ImG;
    	return img;
    	
    }
    
	public boolean mouseMove(Event theEvent,int x,int y)throws IOException{

		g.setFont(f);
		g.setColor(Color.black);
		
		double i = (double)x;

		g.drawString("test",x,y);
		img_r=img(img_right);
		img_r=rotateImage(img_r,x);
		g.drawImage(img_r,250,250,this);
		

		return true;
	}

}
```

momentan is das problem das mouseMove nicht kompatibel mit throws IOException ist aber vielleicht wärs besser da nochmal neu mit "etwas" weniger code anzufangen.

ich bedanke mich schon mal im voraus.


----------



## piOlinO (23. Januar 2008)

Hallo!

Ich bin im Vergleich zu euch wohl noch ein Anfänger ^^ Wir arbeiten im Informatik Unterricht gerade an einem Projekt, wo wir ein Rectangle drehen müssen. Ich habe hier jetzt ein paar Quelltexte gefunden, die mir weitergeholfen haben, aber ich weiß nicht, welchen Parameter ich eingeben muss als inputImage? Also muss ich dafür z.B. nen Pfad eingeben(habe ich schon probiert, aber geht nicht) oder nen Objekt oder was?


```
public static BufferedImage rotateImage(BufferedImage inputImage,...
```

Vielen Dank schonmal


----------



## Thomas Darimont (23. Januar 2008)

Hallo,

schau mal hier:
http://www.tutorials.de/forum/coder...und-breite-einer-rotierten-box-berechnen.html

Gruß Tom


----------



## Bäästy (24. Januar 2008)

hallo ich bins nochmal ^^

für den der sich für mein problem 2 posts oberhalt interessiert:

das problem war dass ich kein bufferedimage bekommen hab weil ich ja in einem applet arbeite. ich habs dann so lösen können das ich ein image in ein garphics gemalt hab und des dann in bufferedimage 'umgewandelt' hab

mfg bäästy


----------



## CMN (20. Oktober 2008)

Um die schwarzen Streifen zu vermeiden reicht es schon den richtigen Drehpunkt anzugeben. Ihr habt immer die Bildmaße als Integer übergeben, z.B. 
	
	
	



```
AffineTransform.getRotateInstance(Math.toRadians(degrees), src.getWidth() / 2, src.getHeight() / 2);
```
Dadurch war der Drehpunkt immer etwas verschoben und kann auch nicht durch Translation (mit Ganzzahlen) korrigiert werden. Um es kurz zu machen, mit

```
AffineTransform.getRotateInstance(Math.toRadians(degrees), src.getWidth() / 2D, src.getHeight() / 2D);
```
sollte es funktionieren.


----------



## SYn4pSE (27. Juli 2009)

Ist zwar alt der Thread, aber falls noch i-wer die Lösung sucht...


```
BufferedImage rotatedImage = new BufferedImage(srcImage.getHeight(), srcImage.getWidth(), srcImage.getType());
AffineTransform affineTransform = AffineTransform.getRotateInstance(Math.toRadians(90), rotatedImage.getWidth() / 2d, srcImage.getHeight() / 2d);
Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
g.setTransform(affineTransform);
g.drawImage(srcImage, 0, 0, null);
```


```
Ich versuchs mal darzustellen:

 __________
|          |
|          |
|__________|
(wäre "srcImage" im obigen Quellcode)
 ______
|      |
|      |
|      |
|      |
|______|
(wäre "rotatedImage " im obigen Quellcode)

legt man nun beide übereinander sieht man den korrekten Drehpunkt!

 _________
|     |   |
|  *  |   |
|_____|___|
|     |
|_____|
```


Funktioniert zumindest in meinem Anwendungsfall, da das gedrehte Image ab demselben Punkt angezeigt werden soll.


----------



## nullGrind (15. Februar 2010)

Hallo liebe Leute.

ich habe den Code von Tom mal angewandt und mein Problem ist es nun, dass sich das BufferedImage beim drehen "auflöst". D.h. benachbarte Pixel Wandern auseinander, sieht aus als ob man das Image in einen Mixer geworfen hätte. Dies sind die beiden functions die ich ausprobiert habe, beide produzieren den selben komischen Fehler:

```
public static BufferedImage rotate(BufferedImage img, int dir1) {
        int w = img.getWidth();
        int h = img.getHeight();
        BufferedImage dimg = dimg = new BufferedImage(w, h, img.getType());
        Graphics2D g = dimg.createGraphics();
        g.rotate(Math.toRadians(angle), w / 2, h / 2);
        g.drawImage(img, null, 0, 0);
        g.dispose();
        return dimg;
}
```


```
public static BufferedImage rotate(BufferedImage img, int dir1) {
AffineTransform affineTransform = AffineTransform.getRotateInstance(Math.toRadians(dir1),
                img.getWidth() / 2,
                img.getHeight() / 2);
        BufferedImage rotatedImage = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
        Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
        g.setTransform(affineTransform);
        g.drawImage(img, 0, 0, null);
        return rotatedImage;
}
```

Und hier noch das aufrufen der Funktion:

```
rocketP1 = Game.rotate(rocketP1, dir1);
```


Zusätzlich bekomm ich noch diesen Output. Ich weiß nicht ob dies mein Problem betrifft:

Exception in thread "Thread-2" java.lang.IllegalStateException: Component must have a valid peer
        at java.awt.Component$FlipBufferStrategy.getBackBuffer(Component.java:3817)
        at java.awt.Component$FlipBufferStrategy.updateInternalBuffers(Component.java:3800)
        at java.awt.Component$FlipBufferStrategy.revalidate(Component.java:3915)
        at java.awt.Component$FlipBufferStrategy.revalidate(Component.java:3897)
        at java.awt.Component$FlipBufferStrategy.getDrawGraphics(Component.java:3889)
        at spacehulks.Game$1.run(Main.java:94)


----------



## Orb (5. Januar 2011)

spitzen beiträge habt mir alle super geholfen!


----------



## johannes_k (31. August 2013)

ein nerviges thema.. aber es geht doch 

hier mein klasse zum drehen in beliebigem winkel und um 90°:

```
package johnny.tests;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;

/**
 * Class for rotating <code>BufferedImage</code>s.
 */
public final class ImageRotater {

	/**
	 * Private constructor.
	 */
	private ImageRotater() {
	}

	/**
	 * Rotates image and adjust image size.
	 */
	public static BufferedImage rotateImage(BufferedImage src, double degrees) {
		Point srcSize = new Point(src.getWidth(), src.getHeight());
		Point dstSize = rectangleExtendAfterRotation(srcSize.x, srcSize.y,
				degrees);

		int correctionX = dstSize.x - srcSize.x;
		int correctionY = dstSize.y - srcSize.y;

		AffineTransform affineTransform = AffineTransform.getRotateInstance(
				Math.toRadians(degrees), srcSize.x / 2 + correctionX / 2,
				srcSize.y / 2 + correctionY / 2);
		BufferedImage rotatedImage = new BufferedImage(dstSize.x, dstSize.y,
				src.getType());
		Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
		g.setTransform(affineTransform);
		g.drawImage(src, correctionX / 2, correctionY / 2, null);
		return rotatedImage;
	}

	/**
	 * Calculates the size of the canvas, that a justified rectangle needs after
	 * rotation.
	 * 
	 * @param width
	 *            of the rectangle
	 * @param height
	 *            of the rectangle
	 * @param d
	 *            rotation in degrees
	 * @return
	 */
	private static Point rectangleExtendAfterRotation(int width, int height,
			double d) {
		Point2D.Double center = new Point2D.Double((double) width / 2,
				(double) height / 2);
		double degree = Math.toRadians(d);

		// get rotated corners
		Point2D.Double newCorner1 = rotatedPoint(new Point2D.Double(0, 0),
				center, degree);
		Point2D.Double newCorner2 = rotatedPoint(new Point2D.Double(width, 0),
				center, degree);
		Point2D.Double newCorner3 = rotatedPoint(new Point2D.Double(width,
				height), center, degree);
		Point2D.Double newCorner4 = rotatedPoint(new Point2D.Double(0, height),
				center, degree);

		// get extend of rotated rectangle
		double minX = Math.min(Math.min(newCorner1.x, newCorner2.x),
				Math.min(newCorner3.x, newCorner4.x));
		double maxX = Math.max(Math.max(newCorner1.x, newCorner2.x),
				Math.max(newCorner3.x, newCorner4.x));
		double minY = Math.min(Math.min(newCorner1.y, newCorner2.y),
				Math.min(newCorner3.y, newCorner4.y));
		double maxY = Math.max(Math.max(newCorner1.y, newCorner2.y),
				Math.max(newCorner3.y, newCorner4.y));

		return new Point((int) (Math.ceil(maxX) - Math.floor(minX)),
				(int) (Math.ceil(maxY) - Math.floor(minY)));
	}

	/**
	 * Rotates one point around another by a specified degree.
	 * 
	 * @param pointToBeRotated
	 * @param centerTobeRotatedAround
	 * @param degree
	 *            in radians
	 * @return rotated point
	 */
	private static Point2D.Double rotatedPoint(Point2D.Double pointToBeRotated,
			Point2D.Double centerTobeRotatedAround, double degree) {

		double dstAngle = Math.atan2(pointToBeRotated.x
				- centerTobeRotatedAround.x, pointToBeRotated.y
				- centerTobeRotatedAround.y)
				+ degree;
		double circleDistance = distance(centerTobeRotatedAround.x,
				centerTobeRotatedAround.y, pointToBeRotated.x,
				pointToBeRotated.y);

		return new Point2D.Double(centerTobeRotatedAround.x
				+ Math.sin(dstAngle) * circleDistance,
				centerTobeRotatedAround.y + Math.cos(dstAngle) * circleDistance);
	}

	/**
	 * Calculates the distance from one point to another.
	 */
	private static double distance(double x1, double y1, double x2, double y2) {
		return Math.sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
	}

	/**
	 * Rotates an image 90° clockwise.
	 * 
	 * @param src
	 * @return
	 */
	public static BufferedImage rotateImageRight(BufferedImage src) {
		return tiltImage(src, true);
	}

	/**
	 * Rotates an image 90° counter-clockwise.
	 * 
	 * @param srcImage
	 * @return
	 */
	public static BufferedImage rotateImageLeft(BufferedImage src) {
		return tiltImage(src, false);
	}

	/**
	 * Rotate image 90°.
	 */
	private static BufferedImage tiltImage(BufferedImage src, boolean clockwise) {
		BufferedImage rotatedImage = new BufferedImage(src.getHeight(),
				src.getWidth(), src.getType());
		AffineTransform affineTransform;
		if (clockwise)
			affineTransform = AffineTransform.getRotateInstance(
					Math.toRadians(90), rotatedImage.getWidth() / 2d,
					src.getHeight() / 2d);
		else
			affineTransform = AffineTransform.getRotateInstance(
					Math.toRadians(270), src.getWidth() / 2d,
					rotatedImage.getHeight() / 2d);
		Graphics2D g = (Graphics2D) rotatedImage.getGraphics();
		g.setTransform(affineTransform);
		g.drawImage(src, 0, 0, null);
		return rotatedImage;
	}
}
```

allerdings:
kurz nachdem ich damit fertig war, bin ich auf eine kürzere implementation gestoßen... ._. (ImageTool)
hier der auf BufferedImage angepasste code:

```
/**
	 * adapted from
	 * https://code.google.com/p/game-engine-for-java/source/browse/
	 * src/com/gej/util/ImageTool.java
	 */
	public static BufferedImage rotateImageX(BufferedImage img, double angle) {
		double sin = Math.abs(Math.sin(Math.toRadians(angle))), cos = Math
				.abs(Math.cos(Math.toRadians(angle)));
		int w = img.getWidth(null), h = img.getHeight(null);
		int neww = (int) Math.floor(w * cos + h * sin), newh = (int) Math
				.floor(h * cos + w * sin);
		BufferedImage bimg = new BufferedImage(neww, newh,
				BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = bimg.createGraphics();
		g.translate((neww - w) / 2, (newh - h) / 2);
		g.rotate(Math.toRadians(angle), w / 2, h / 2);
		g.drawRenderedImage(img, null);
		g.dispose();
		return bimg;
	}
```

damit kann vielleicht der thread als gelöst markiert werden..


----------

