AWT graphics2d transform

Diskutiere graphics2d transform im AWT, Swing, JavaFX & SWT Bereich.
L

liann

Hallo, ich habe ein Bild, was unter umständen gedreht dargestellt werden soll. Dazu habe ich folgende zeilen geschrieben
Java:
       g2 = (Graphics2D) g2.create();
        g2.rotate(Math.toDegrees(rotation));
        g2.drawImage(img(), xCoordinate(), yCoordinate(), null);
        if (rotationDraw != null) rotationDraw.draw(g2);
        g2.dispose();
wenn rotation == 0 ist, klappt alles, andernfalls sehe ich das bild einfach nicht. Ich denke mal das Bild ist an irgendeiner Stelle gezeichnet, ich weiß aber 1. nicht wo und 2. nicht wie ich es den Koordinaten xCoordinate() und yCoordinat() zeichnen kann. Wie geht das am Besten?
Ich habe auch mir transform und 3 parametern versucht, klappte aber auch nicht.
Code:
            g2.setTransform(AffineTransform.getRotateInstance(Math.toDegrees(rotation),
                    xCoordinate() + img().getWidth() / 2d,
                    yCoordinate() + img().getHeight() / 2d));
 
R

realodds

Java:
public static void drawRotatedImage(BufferedImage image,
                                        double degrees, int x, int y, Graphics2D g2) {
        double rX = image.getWidth() / 2d;
        double rY = image.getHeight() / 2d;
        AffineTransform tx = AffineTransform
                .getRotateInstance(Math.toRadians(degrees), rX, rY);
        AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
        g2.drawImage(image, op, x, y);
    }
 
N

NoName2

Bitte möglichst immer vollständige Beispiele angeben, so ginge es auch:
Java:
	public static void rot(String img, int degree) throws IOException {
		BufferedImage i = ImageIO.read(new File(img));
		JFrame f = new JFrame() {
			@Override
			public void paint(Graphics g) {
				super.paint(g);
				Graphics2D g2d = (Graphics2D) g;
				g2d.rotate(Math.toRadians(degree));

				Point2D p2 = new Point();
				AffineTransform.getRotateInstance(Math.toRadians(degree)).transform(new Point(0, i.getHeight()), p2);

				g2d.drawImage(i, (int) Math.ceil(-p2.getX()), 0, null);
			}
		};
		f.setSize(800, 800);
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.setVisible(true);
	}

	public static void main(String[] args) throws IOException {
		rot("...png", 35);
	}
nur aus irgendeinem Grund berechnet er die Bounding-Box (AffineTransform) bei mir falsch. :(
 
N

NoName2

Man sollte besser mit einer Canvas zeichnen 🤦‍♂️
Tatsächlich ist es so, dass ungefähr bis 20 Grad die BB richtig berechnet wird, danach aber nicht mehr:
Java:
	public static void rot(String img, int degree) throws IOException {
		BufferedImage i = ImageIO.read(new File(img));
		JFrame f = new JFrame();
		f.add(new Canvas() {
			@Override
			public void paint(Graphics g) {
				super.paint(g);
				Graphics2D g2d = (Graphics2D) g;
				g2d.rotate(Math.toRadians(degree));

				int min = 0;
				for (int j = 0; j <= i.getHeight(); j++) {
					int x2 = (int) -(j * Math.sin(Math.toRadians(degree)));
					if (x2 < min) {
						min = x2;
					}
				}
				System.out.println(min);

				g2d.drawImage(i, -min, 0, null);
			}
		});
		f.setSize(800, 800);
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.setVisible(true);
	}
 
N

NoName2

Ja aber du rotierst auch um den Mittelpunkt... ich weiß nicht, warum es sich so seltsam am linken Rand verhält, wenn um (0, 0) rotiert wird...
 
N

NoName2

Nach 5 Tagen... hab ich es doch noch hinbekommen... es richtig zu machen und die BoundingBox sowie translate und rotate in der richtigen Reihenfolge aufzurufen:
Java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.WindowConstants;

public class RotImg {
	public static Rectangle2D getRotRec(AffineTransform at, int w, int h) {
		int minx = 0;
		int miny = 0;
		int maxx = 0;
		int maxy = 0;
		for (int j = 0; j < 4; j++) {
			Point p1 = new Point((j & 1) == 0 ? 0 : (w - 1), (j & 2) == 0 ? 0 : (h - 1));
			Point p2 = new Point();
			at.transform(p1, p2);
			if (p2.x < minx) {
				minx = p2.x;
			}
			if (p2.y < miny) {
				miny = p2.y;
			}
			if (p2.x > maxx) {
				maxx = p2.x;
			}
			if (p2.y > maxy) {
				maxy = p2.y;
			}
		}
		return new Rectangle(minx, miny, maxx - minx, maxy - miny);
	}

	public static void rot(String img) throws IOException {
		BufferedImage i = ImageIO.read(new File(img));
		JSlider js = new JSlider(0, 360, 0);
		Canvas cs = new Canvas() {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void paint(Graphics g) {
				super.paint(g);

				int degree = js.getValue();
				AffineTransform at = new AffineTransform();
				at.rotate(Math.toRadians(degree), i.getWidth() / 2.0, i.getHeight() / 2.0);
				Rectangle2D rec = getRotRec(at, i.getWidth(), i.getHeight());

				AffineTransform at2 = new AffineTransform();
				at2.translate(-rec.getMinX(), -rec.getMinY());
				at2.rotate(Math.toRadians(degree), i.getWidth() / 2.0, i.getHeight() / 2.0);

				Graphics2D g2d = (Graphics2D) g;
				g2d.drawRect(0, 0, (int) rec.getWidth(), (int) rec.getHeight());
				g2d.setTransform(at2);
				g2d.drawImage(i, 0, 0, null);
			}
		};

		JFrame f = new JFrame();
		f.setLayout(new BorderLayout());
		f.add(cs, BorderLayout.CENTER);
		f.add(js, BorderLayout.SOUTH);
		f.setSize(1000, 1000);
		f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		f.setVisible(true);

		js.addChangeListener((e) -> {
			JSlider src = (JSlider) e.getSource();
			//if (!src.getValueIsAdjusting()) {
				cs.repaint();
			//}
		});
	}

	public static void main(String[] args) throws IOException {
		rot("Pfad eintragen");
	}
}
Probierts mal aus!
 
Thema: 

graphics2d transform

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben