Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Help? AffineTransform scale around a point

Featured Replies

I want to be able to zoom in using scaling but right now it scales relative to the top left corner and I want to be able to scale based on my mouse position. Does any one have any ideas on how I can make this happen?

 

51b8971846720785fc05d60a6ff7209d.gif

 

This is how it looks as of now, scaling into the top left corner.

 

Code:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class PictureFrame {
	
	private ImageCanvas canvas;
	
	public PictureFrame(String filePath) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createFrame(filePath);
			}
		});
	}
	
	public PictureFrame(Image image) {
		javax.swing.SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				createFrame(image);
			}
		});
	}

	private void createFrame(String filePath) {
		JFrame frame = new JFrame("Picture Frame Test");
		frame.setSize(800, 600);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		canvas = new ImageCanvas(filePath, frame.getWidth(), frame.getHeight());

		frame.getContentPane().add(canvas);
		frame.setVisible(true);
	}
	
	private void createFrame(Image image) {
		JFrame frame = new JFrame("Picture Frame Test");
		frame.setSize(800, 600);
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		canvas = new ImageCanvas(image, frame.getWidth(), frame.getHeight());

		frame.getContentPane().add(canvas);
		frame.setVisible(true);
	}

	private class ImageCanvas extends JComponent {

		private Image image;
		private AffineTransform transformer = new AffineTransform();

		ImageCanvas(String filePath, int width, int height) {
			try {
				image = ImageIO.read(new File(filePath));
				setSize(width, height);
				EventListener eventListener = new EventListener();
				addMouseListener(eventListener);
				addMouseWheelListener(eventListener);
				addMouseMotionListener(eventListener);
			} catch (IOException e) {
				System.out.println("Unable to read image file!");
			}

		}
		
		ImageCanvas(Image image, int width, int height) {
				this.image = image;
				setSize(width, height);
				EventListener eventListener = new EventListener();
				addMouseListener(eventListener);
				addMouseWheelListener(eventListener);
				addMouseMotionListener(eventListener);

		}
		
		public double getMinScale(){
			
			double limitX = (double) canvas.getWidth() / (double) canvas.getImage().getWidth(null);
			double limitY = (double) canvas.getHeight() / (double) canvas.getImage().getHeight(null);
			
			return (limitX > limitY) ? limitX : limitY;
		}
		
		public Image getImage(){
			return image;
		}
		
		public AffineTransform getTransformer(){
			return transformer;
		}

		@[member=Override]
		protected void paintComponent(Graphics g) {
			try {
				Graphics2D graphics = (Graphics2D) g;
				graphics.setTransform(transformer);
				Point mouse = MouseInfo.getPointerInfo().getLocation();
				SwingUtilities.convertPointFromScreen(mouse, this);
				graphics.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null);
				graphics.setColor(Color.BLACK);
				graphics.fillRect(0, 0, 90, 15);
				graphics.setColor(Color.WHITE);
				graphics.drawString(String.format("X: %.0f Y: %.0f", mouse.getX(), mouse.getY()), 10, 10);
				Thread.sleep(15);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private class EventListener implements MouseListener, MouseWheelListener, MouseMotionListener {
		
		private Point startPoint, endPoint;
		private double deltaX, deltaY;
		
		
		@[member=Override]
		public void mouseWheelMoved(MouseWheelEvent e) {
			AffineTransform transformer = canvas.getTransformer();
			
			if(e.getWheelRotation() < 0)
				transformer.setToScale(transformer.getScaleX() + .05, transformer.getScaleY() + .05);
			else
				transformer.setToScale(Math.max(canvas.getMinScale(), transformer.getScaleX() - .05), Math.max(canvas.getMinScale(), transformer.getScaleY() - .05));
			
			
			 transformer.translate(deltaX, deltaY);
			 canvas.repaint();
		}
		
		@[member=Override]
		public void mouseClicked(MouseEvent e) {
			
		}

		@[member=Override]
		public void mousePressed(MouseEvent e) {
			startPoint = e.getPoint();
		}

		@[member=Override]
		public void mouseReleased(MouseEvent e) {

		}

		@[member=Override]
		public void mouseEntered(MouseEvent e) {

		}

		@[member=Override]
		public void mouseExited(MouseEvent e) {

		}

		@[member=Override]
		public void mouseDragged(MouseEvent e) {
			AffineTransform transformer = canvas.getTransformer();
			 try {
		            endPoint = e.getPoint();
		            Point dragStart = transformPoint(startPoint);
		            Point dragEnd = transformPoint(endPoint);
		            /*
		            double dx = dragEnd.getX() - dragStart.getX();
		            double dy = dragEnd.getY() - dragStart.getY();
		            deltaX += dx;
		            deltaY += dy;
		            */
		             double deltaW = (double) canvas.getWidth() - (double) canvas.getImage().getWidth(null) * transformer.getScaleX();
					 double deltaH = (double) canvas.getHeight() - (double) canvas.getImage().getHeight(null) * transformer.getScaleY();
					 double px = Math.max(deltaW, Math.min(0, deltaX + (dragEnd.getX() - dragStart.getX())));
					 double dx = px - deltaX;
					 double py = Math.max(deltaH, Math.min(0, deltaY + (dragEnd.getY() - dragStart.getY())));
					 double dy = py - deltaY;
					 deltaX = px;
					 deltaY = py;
		            
		            transformer.translate(dx, dy);
		            startPoint = endPoint;
		            endPoint = null;
		        } catch (NoninvertibleTransformException ex) {
		            ex.printStackTrace();
		        }
			canvas.repaint();
		}

		@[member=Override]
		public void mouseMoved(MouseEvent e) {
			canvas.repaint();
		}
		
		private Point transformPoint(Point p1) throws NoninvertibleTransformException{
			AffineTransform transformer = canvas.getTransformer();
			AffineTransform inverse = transformer.createInverse();
	        Point p2 = new Point();
	        inverse.transform(p1, p2);
	        return p2;
		}

	}

}

I reckon you should translate the transformed image according to your mouse.

				Graphics2D graphics = (Graphics2D) g;
				graphics.setTransform(transformer);
				Point mouse = MouseInfo.getPointerInfo().getLocation();
				SwingUtilities.convertPointFromScreen(mouse, this);
                                > graphics.translate(-mouse.getX() * graphics.getTransform().getScaleX(), -mouse.getY() * graphics.getTransform().getScaleY());
				graphics.drawImage(image, 0, 0, image.getWidth(null), image.getHeight(null), null);
                                > graphics.translate(mouse.getX() * graphics.getTransform().getScaleX(), mouse.getY() * graphics.getTransform().getScaleY());
				graphics.setColor(Color.BLACK);
				graphics.fillRect(0, 0, 90, 15);
				graphics.setColor(Color.WHITE);
				graphics.drawString(String.format("X: %.0f Y: %.0f", mouse.getX(), mouse.getY()), 10, 10);

Just a guess tho, haven't tried compiling your code

EDIT: remember to translate back :boge:

Edited by FrostBug

try something like this

            AffineTransform transformer = canvas.getTransformer();
            Point p = e.getPoint();
            int mouseX = p.x;
            int mouseY = p.y;
            double zoom = e.getUnitsToScroll() < 0 ? 1.05 : 1 / 1.05;
            deltaX = (int) ((transformer.getTranslateX() * zoom) - ((mouseX * zoom) - mouseX));
            deltaY = (int) ((transformer.getTranslateY() * zoom) - ((mouseY * zoom) - mouseY));
            transformer.setToScale(transformer.getScaleX() * zoom, transformer.getScaleY() * zoom);
            transformer.translate(deltaX, deltaY);
            canvas.repaint();

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.