SWT Transform

lumo

Top Contributor
Transform = Mein Kampf

ich habe ein bild (img) mit 64x64 px das ich drehen will und dann auf ein größeres bild (canvas) zeichnen will...

was muss ich tun um das bild zuerst um seinen mittelpunkt (32/32) zu drehen und dann auf einen punkt (mauscursor) zu zeichnen???

Code:
also hab ich
img = rect {0,0,64,64}
canvas = rect {0,0,361,185}
mousePos = point {x,y}
ich dachte:
Java:
...
transform.translate(img.width/2, img.height/2);
transform.rotate(getNextRotation());
transform.translate(-img.width / 2, -img.height / 2);
...
gc.drawImage(buffer, mousePos.x, mousePos.y);
kommt aber schwachsinn raus, das ding dreht sich zwar fliegt aber unkontrolliert rum...
 

Marco13

Top Contributor
So ganz falsch sollte das nicht sein (auch wenn ich da auch immer irgendeinen Furz-(Vorzeichen)-Fehler mache :oops: ). Kann man da schnell ein KSKB drumbasteln?
 

lumo

Top Contributor
so, bin erst jetzt dazu gekommen das kleine programm zu schreiben....
das loading.png ist einfach eine bilddatei, die 64x64px hat... meine hat einen transparenten hintergrund.

Java:
package tests;

import java.awt.Point;
import java.io.File;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Shell;

public class SampleTransform {

	protected Shell shell;
	private Image img;
	private Display display;
	private int rotation = 0;
	private Point mousePos = new Point(0, 0);

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			SampleTransform window = new SampleTransform();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {
		display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	private int getNextRotation() {
		rotation = (rotation + 1) % 360;
		return rotation;
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setSize(450, 300);
		shell.setText("SWT Application");
		shell.setLayout(new GridLayout(3, false));

		Group grpOriginal = new Group(shell, SWT.NONE);
		grpOriginal.setLayout(new GridLayout(1, false));
		grpOriginal.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false,
				1, 1));
		grpOriginal.setText("Original");

		img = new Image(display, new File("").getAbsolutePath()
				+ "/res/loading.png");

		Composite cOrig = new Composite(grpOriginal, SWT.NONE);
		cOrig.addPaintListener(new PaintListener() {

			@Override
			public void paintControl(PaintEvent e) {
				e.gc.drawImage(img, 0, 0);

			}
		});

		Group grpRotated = new Group(shell, SWT.NONE);
		grpRotated.setLayout(new GridLayout(1, false));
		grpRotated.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false,
				1, 1));
		grpRotated.setText("Rotated");

		final Composite cRotated = new Composite(grpRotated, SWT.NONE
				| SWT.DOUBLE_BUFFERED);
		cRotated.addMouseMoveListener(new MouseMoveListener() {

			@Override
			public void mouseMove(MouseEvent arg0) {
				cRotated.redraw();
			}
		});
		cRotated.addPaintListener(new PaintListener() {

			@Override
			public void paintControl(PaintEvent e) {
				Transform oldTransform = new Transform(display);
				e.gc.getTransform(oldTransform);

				Transform t = new Transform(display);
				t.translate(img.getBounds().width / 2,
						img.getBounds().height / 2);
				t.rotate(getNextRotation());
				t.translate(-(img.getBounds().width / 2),
						-(img.getBounds().height / 2));
				e.gc.setTransform(t);
				e.gc.drawImage(img, 0, 0);

				t.dispose();
				e.gc.setTransform(oldTransform);
				oldTransform.dispose();
			}
		});

		Group grpRotatedOnTarget = new Group(shell, SWT.NONE);
		grpRotatedOnTarget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,
				true, 1, 1));
		grpRotatedOnTarget.setText("Rotated on target");
		grpRotatedOnTarget.setLayout(new GridLayout(1, false));

		final Composite cBig = new Composite(grpRotatedOnTarget, SWT.NONE | SWT.DOUBLE_BUFFERED);
		cBig.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		cBig.addMouseMoveListener(new MouseMoveListener() {

			@Override
			public void mouseMove(MouseEvent me) {
				mousePos.x = me.x;
				mousePos.y = me.y;
				cBig.redraw();
			}
		});
		cBig.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				Transform oldTransform = new Transform(display);
				e.gc.getTransform(oldTransform);

				Transform t = new Transform(display);
				t.translate(img.getBounds().width / 2,
						img.getBounds().height / 2);
				t.rotate(getNextRotation());
				t.translate(-(img.getBounds().width / 2),
						-(img.getBounds().height / 2));
				e.gc.setTransform(t);
				e.gc.drawImage(img, mousePos.x, mousePos.y);

				t.dispose();
				e.gc.setTransform(oldTransform);
				oldTransform.dispose();
			}
		});
	}
}

wie du sehen kannst klappt das alles ganz gut bis auf den teil drei.
hinweis: ich kann das gedrehte bild nicht zwischenspeichern, da ich das ganze zweimal mache - einmal für die farben, und einmal für den alpha kanal (in meiner app dann...)

sonst wärs leichter... bild drehen, zwischenspeichern, und dann drauf malen... (wobei es trotzdem gehen muss - das direkt zu machen)
 

Marco13

Top Contributor
Ah ja nee... bei drawImage ist die Mausposition angegeben, aber die Transform wurde ja schon auf's GC angewendet... Das Bild soll quasi immer um seinen Mittelpunt (an der Mausposition) rotieren?
Java:
        cBig.addPaintListener(new PaintListener() {
            @Override
            public void paintControl(PaintEvent e) {
                Transform oldTransform = new Transform(display);
                e.gc.getTransform(oldTransform);
 
                Transform t = new Transform(display);
                int cx = img.getBounds().width / 2;
                int cy = img.getBounds().height / 2;
                t.translate(mousePos.x, mousePos.y);
                t.rotate(getNextRotation());
                t.translate(-cx, -cy);
                e.gc.setTransform(t);
                e.gc.drawImage(img, 0, 0);
 
                t.dispose();
                e.gc.setTransform(oldTransform);
                oldTransform.dispose();
            }
        });
 

lumo

Top Contributor
habs jetzt so gemacht...
doch noch nen buff eingefügt, denn ich weiss nicht wie swt reagiert wenn ich bilder mit 5000+px rotieren will... ;)
Java:
gc.setAdvanced(true);
		if (!gc.getAdvanced()) {
			gc.drawText("Advanced graphics not supported", 30, 30, true);
			return;
		}
		if (buff == null || buff.isDisposed()) {
			buff = new Image(Display.getDefault(), this.image.getBounds());
		}

		GC buffGC = new GC(buff);
		Transform oldTransform = new Transform(buffGC.getDevice());
		buffGC.getTransform(oldTransform);
		Transform transform = new Transform(buffGC.getDevice());

		transform.translate(image.getBounds().width / 2,
				image.getBounds().height / 2);
		transform.rotate(getNextRotation());
		transform.translate(-(image.getBounds().width / 2),
				-(image.getBounds().height / 2));

		buffGC.setTransform(transform);
		buffGC.drawImage(image, 0, 0);
		if (getMousePos() != null) {
			gc.drawImage(buff, getMousePos().x - image.getBounds().width / 2,
					getMousePos().y - image.getBounds().height / 2);
			System.out.println(getMousePos());
		} else {
			gc.drawImage(buff, 0, 0);
		}
		transform.dispose();
		oldTransform.dispose();
		buff.dispose();
 

Ähnliche Java Themen


Oben