[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Copy image from a canvas, zoom it and put it into the same canvas (JAVA graphics 2D)

Posted on 2009-04-21
12
Medium Priority
?
1,167 Views
Last Modified: 2013-12-29
Hi!
I would like to get a code tha copies an image from a canvas (to a buffer), zoom it (in or out) and put it once again on the same canvas. The reason is I have problems using the AffineTransformation in Java and preffer to use that this method. Anyone can help me?
Thanks in advance!
0
Comment
Question by:profesoralex2
12 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 24199410
>>The reason is I have problems using the AffineTransformation in Java

What problems?
0
 
LVL 17

Expert Comment

by:Thomas4019
ID: 24199694
This way of copying sounds inefficient. What is use for advanced graphics is the simple methods in Graphics2D. If i want to scale everything i draw by 2. I use g.scale(2,2) , and then call the drawImage or drawLine commands.
0
 
LVL 17

Expert Comment

by:Thomas4019
ID: 24199811
Here is a sample program showing transforms
import javax.swing.*;
import java.awt.*;
 
class SampleGraphics extends JFrame
{
	double time = 0;
 
	SampleGraphics()
	{
		setSize(640,480);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
 
		while(true)
		{
			time++;
			paint();
 
			try
			{
				Thread.sleep(30);
			}
			catch(Exception e){e.printStackTrace();}
		}
	}
 
	public void paint()
	{
		if(getBufferStrategy() == null)
			createBufferStrategy(2);   //Set double buffering
 
		Graphics2D g = (Graphics2D)getBufferStrategy().getDrawGraphics();  //Get double buffered graphics
 
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
 
		g.setColor(Color.WHITE);
		g.fillRect(0,0,getWidth(),getHeight());
 
		//ORDER IS VERY SIGNIFICANT WITH TRANSFORMATIONS
 
		g.translate(350,250); //Shifts left 350 pixels and down 250 pixels
		g.scale(time%100/200,time%100/200);
		g.rotate(time/100,150,150);
 
		g.setColor(Color.BLUE);
		g.drawLine(100,100,200,100);
		g.drawLine(100,100,100,200);
		g.drawLine(200,200,200,100);
		g.drawLine(200,200,100,200);
		g.drawLine(100,100,200,200);
		g.drawLine(100,200,200,100);
 
		getBufferStrategy().show();
	}
 
	public static void main(String args[])
	{
		new SampleGraphics();
	}
}

Open in new window

0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:profesoralex2
ID: 24210116
Ok, Thanks to all! My problem is not to make a zoom, but make a zoom and paint! Could someone give me a code to zoom in a canvas image and paint on it(by hand)? I observe that the zooming doenst work properly (not centered when I use the scrollbar) and doesn't paint fine (the cursor is moved when I try to paint something). So it's a reason to use a buffered image, copying it, zooming it and putting it on the canvas. Also I observe when I use the affine transform zooming out, the canvas area is also reduced. I realize that I need to do something with the affine transform parameters but I'am new in it. Could anyone help me?
Thanks!!!!

Alex
0
 
LVL 17

Expert Comment

by:Thomas4019
ID: 24210648
Could you post your problematic code?
0
 

Author Comment

by:profesoralex2
ID: 24219487
Ok! See my code related to affineTransform: Basically I have a canvas I paint into. I have a zoom in button. When I want to zoom I use  tx.translate(WhiteboardContext.WIDTH/2, WhiteboardContext.HEIGHT/2);
scale it and paint it. The problem is when I zoom it the zoom is not centered and also when I zoom out I get then image I attached. So bascically what I want is:
1) get the image from my canvas
2) zoom it (in or out)
3) put it into my canvas
With this method the canvas size still the same.
Thank you!!!!

Alex
public class Whiteboard extends Canvas implements MouseListener,
						  MouseMotionListener,
						  KeyListener,
						  ActionListener,
						  WhiteboardContext{
......................
private AffineTransform tx = new AffineTransform();
 
......................
 
 
public void paintContents(Graphics g) {
     ((Graphics2D) g).setTransform(tx);
     //((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
	    currentShape.paint(this, g);
    }
 
    else if (buttonin == zoom_in){
        System.out.println("zoom_in");
    tx.translate(WhiteboardContext.WIDTH/2, WhiteboardContext.HEIGHT/2);
 
    tx.scale(1.5,1.5);
 
    }
 else if (buttonin == zoom_out){
        System.out.println("zoom_out");
    tx.translate((WhiteboardContext.WIDTH-20)*(1-1/1.5)/4, WhiteboardContext.HEIGHT*(1-1/1.5)/4);
    tx.scale(1/1.5,1/1.5);
    }

Open in new window

Imagen-2.png
Imagen-3.png
0
 
LVL 17

Expert Comment

by:Thomas4019
ID: 24220467
This was a tricky problem. The reason why I really dont want to do your canvas resizing way is that it kind of ruins to point of zooming. The quality wouldn't be any better and the antialiasing would be mostly lost. Also scaling images takes processing time for it to be inconvient to do it every frame.

I took your code and changed a little so i could run it, then i added three variables, centerX, centerY, zoom. Everytime the canvas paints, it zooms the graphics object and translates it so that centerX and centerY are at the center of your screen.

Hope this helps.
import java.awt.*;
import java.awt.geom.*;
 
public class Whiteboard extends Canvas
{
	public static final int WIDTH = 640;
	public static final int HEIGHT = 480;
 
	int centerX = 150;
	int centerY = 150;
	double zoom = 1;
 
	public void paint(Graphics g)
	{
		paintContents(g);
	}
 
	public void paintContents(Graphics g1)
	{
		Graphics2D g = (Graphics2D)g1;
 
		g.translate(WIDTH/2 - centerX * zoom,HEIGHT/2 - centerY * zoom);
		g.scale(zoom,zoom);
 
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
 
		g.setColor(Color.RED);
		g.fillOval(150 - 50,150 - 50,100,100);
 
		g.setColor(Color.BLUE);
		g.fillOval(250 - 25,250 - 25,50,50);
	}
 
	public void zoomIn()
	{
		zoom += 1;
		System.out.println("zoom_in");
	}
 
	public void zoomOut()
	{
		zoom -= 1;
		System.out.println("zoom_out");
	}
}

Open in new window

0
 
LVL 17

Expert Comment

by:Thomas4019
ID: 24220471
Heres some code is used to test this Whiteboard, so you can try it. I basically automates zooming in and then changing the center and then zooming out for testing purposes.
import javax.swing.*;
import java.awt.*;
 
class Sample extends JFrame
{
	Whiteboard w = new Whiteboard();
 
	Sample()
	{
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(640,480);
		setUndecorated(true);
 
		add(w);
 
		setVisible(true);
 
		pause(1000);
 
		w.zoomIn();
		w.repaint();
 
		pause(1000);
 
		w.zoomIn();
		w.repaint();
 
		pause(1000);
 
		w.zoomIn();
		w.repaint();
 
		pause(1000);
 
		w.centerX = 250;
		w.centerY = 250;
		w.repaint();
 
		pause(1000);
 
		w.zoomOut();
		w.repaint();
 
		pause(1000);
 
		w.zoomOut();
		w.repaint();
 
		pause(1000);
 
		w.zoomOut();
		w.repaint();
	}
 
	public static void pause(int i)
	{
		try
		{
			Thread.sleep(i);
		}
		catch(Exception e){}
	}
 
	public static void main(String args[])
	{
		new Sample();
	}
}

Open in new window

0
 

Author Comment

by:profesoralex2
ID: 24285699
Hello, Thomas4019!
Look, your solution seems to be OK, but the problem I find is the cursor "not pointed" when I paint. Please, see the attached pictures (picture 3, after to make a zoom, when I try to paint the cursor's position is not matched with the line).
Thank you!!!

Alex
import java.awt.*;
import java.awt.geom.*;
 
public class Whiteboard extends Canvas
{
	public static final int WIDTH = 640;
	public static final int HEIGHT = 480;
 
	int centerX = 150;
	int centerY = 150;
	double zoom = 1;
 
	public void paint(Graphics g)
	{
		paintContents(g);
	}
 
	public void paintContents(Graphics g1)
	{
		Graphics2D g = (Graphics2D)g1;
 
		g.translate(WIDTH/2 - centerX * zoom,HEIGHT/2 - centerY * zoom);
		g.scale(zoom,zoom);
 
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
 
		g.setColor(Color.RED);
		g.fillOval(150 - 50,150 - 50,100,100);
 
		g.setColor(Color.BLUE);
		g.fillOval(250 - 25,250 - 25,50,50);
	}
 
	public void zoomIn()
	{
		zoom += 1;
		System.out.println("zoom_in");
	}
 
	public void zoomOut()
	{
		zoom -= 1;
		System.out.println("zoom_out");
	}
}

Open in new window

ex1.bmp
ex2.bmp
ex3.bmp
0
 
LVL 17

Accepted Solution

by:
Thomas4019 earned 2000 total points
ID: 24286612
In order to fix the mouse just use these methods to convert from "Screen Coordinates" to "Actual Coordinates". I also attached my mouseMoved method to show you about how these methods would be used.

Hope this helps.
	public void mouseMoved(MouseEvent evt)
	{
		mouseX = convertMouseX(evt.getX());
		mouseY = convertMouseY(evt.getY());
	}
 
	public int convertMouseX(int screenX)
	{
		return (int)((screenX - WIDTH/2)/zoom + centerX);
	}
 
	public int convertMouseY(int screenY)
	{
		return (int)((screenY - HEIGHT/2)/zoom + centerY);
	}

Open in new window

0
 

Author Closing Comment

by:profesoralex2
ID: 31597493
Thomas4019, your solution is exactly what I need. Thank you!
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The purpose of this article is to demonstrate how we can use conditional statements using Python.
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
Suggested Courses
Course of the Month20 days, 7 hours left to enroll

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question