Rotation von BufferedImage (Affine Transformation)

Status
Nicht offen für weitere Antworten.

Pannekuche

Mitglied
Hallo Leute!

Ich habe ein kleines Problemchen beim Rotieren von Bildern. Ich drehe Bilder mithilfe der Klasse AffineTransform. Ich will das Bild nur rechts-, links-, und um 180° drehen. Auf den Kopf stellen (also 180°) funktioniert ohne Probleme, jedoch wenn ich das Bild links- oder rechtsdrehe, scheidet er immer ein Stück vom Bild ab. Ich habe das Buch "Java 2D Api Graphics" von Sun besorgt in dem es recht gut erklärt ist. Ich kann jedoch den Fehler nicht finden. Es wird auch kein temporäres Bild angelegt, sondern das neue Bild direkt in das Alte "gerendert" (mit Hilfe der Filter-Methode).

Hier der Code:
"img" ist ein BufferedImage-Objekt

Code:
AffineTransform rotation = new AffineTransform();
AffineTransformOp rotator;
rotation.rotate(Math.toRadians(ROTATERIGHT), img.getWidth() / 2, img.getHeight() / 2);
rotator = new AffineTransformOp(rotation, AffineTransformOp.TYPE_BILINEAR);
img = rotator.filter(img, null);


In dem Buch steht geschrieben, dass die "filter-Methode" die Groesse des neuen Bildes automatisch bestimmt...
Ich habe es auch schon versucht ein neues Bild zu erstellen, dh

Code:
AffineTransform rotation = new AffineTransform();
AffineTransformOp rotator;
BufferedImage tmp = new BufferedImage(img.getHeight(), img,getWidth(), img,getType()); //width und height sind extra vertauscht
rotation.rotate(Math.toRadians(ROTATERIGHT), img.getWidth() / 2, img.getHeight() / 2);
rotator = new AffineTransformOp(rotation, AffineTransformOp.TYPE_BILINEAR);
img = rotator.filter(img, tmp);
img = tmp;

aber das will auch nicht so recht funktionieren...


Jemand eine Ahnung woran das liegen könnte?
 
Ohne jetzt größer drüber nachzudenken, du weißt schon, dass ein Bild gedreht (mal abgesehen von 90, 180 und 270°) logischerweiße links, rechts, oben und unten mehr Platz braucht als normal?
 
Na klar! Deswegen habe ich ja auch in der 2.Variante Hoehe und Breite des neuen Bildes vertauscht.
Aber wie bereits oben erwähnt berechnet der Filter die benötigte Höhe und Breites des Bildes... Ich kann euch mal ein Screenshot posten (nach dem Drehen). Ich denke eher dass es an dem Rotationspunkt liegt
 
Originalbild:
girry7.png


Gedrehtes Bild:
girrotatedfh8.png
 
Hier meine (ungetestete) Variante:
Code:
public Image rotateImage( Image in )
{
    // Kopie erzeugen
    BufferedImage out = new BufferedImage( in.getHeight(), in.getWidth(), in.getType() );

    // Graphics2D holen
    Graphics2D g = (Graphics2D)out.getGraphics();

    // Drehung um -90 Grad um (0,0)
    g.setTransform( AffineTransform.getQuadrantRotateInstance(-1);

    // Zeichnen des im gedrehten Koordinatensystem nach oben verschobenen Bildes
    g.drawImage( in, 0, -in.getWidth() );

    // fertig
    return out;
}

Klappt das besser???
 
1.
AffineTransform.getQuadrantRotateInstance(-1); //die Methode existiert nicht

2.
g.drawImage( in, 0, -in.getWidth() ); //Darf keine BufferdImage als Parameter enthalten

Ich denke wirklich dass es nur an dem Rotationspunkt liegt, dh
Code:
rotation.rotate(Math.toRadians(ROTATERIGHT), img.getWidth() / 2, img.getHeight() / 2);
Nur wie finde ich diesen heraus?
 
Sorry, habe vollkommen vergessen hierauf nochmal zu antworten:

1: die QuadrantRotate-Methode ist mal wieder aus Java 6 (Beta), hatte ich vergessen zu überprüfen. Nimm stattdessen halt einfach
Code:
g.setTransform( AffineTransform.getRotateInstance(-Math.PI/2) );
2: beim drawImage fehlt natürlich der ImageObserver:
Code:
g.drawImage( in, 0, -in.getWidth(), null );
 
Hallo,


ich kenne mich selber noch nicht so gut mit dem Java 2D API aus, aber ich vermute mal folgendes: Bei einem Filter gibt es immer eine Eingabe/eine Quelle und eine Ausgabe/ein Ziel. Also probier mal:


Falsch (Ziel und Quelle identisch):
Code:
img = rotator.filter(img, null);

Richtig (Ein Ziel und ein Quell-Puffer):
Code:
outputImg = rotator.filter(inputImg, null);


Gruss
Heiko
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben