Bild drehen

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
 
Um die schwarzen Streifen zu vermeiden reicht es schon den richtigen Drehpunkt anzugeben. Ihr habt immer die Bildmaße als Integer übergeben, z.B.
Code:
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
Code:
AffineTransform.getRotateInstance(Math.toRadians(degrees), src.getWidth() / 2D, src.getHeight() / 2D);
sollte es funktionieren.
 
Ist zwar alt der Thread, aber falls noch i-wer die Lösung sucht...

Code:
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);

Code:
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.
 
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:
Code:
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;
}
Code:
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:
Code:
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)
 
Zuletzt bearbeitet:
ein nerviges thema.. aber es geht doch ;)

hier mein klasse zum drehen in beliebigem winkel und um 90°:
Code:
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:
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..
 
Zurück