profesoralex2
asked on
Copy image from a canvas, zoom it and put it into the same canvas (JAVA graphics 2D)
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!
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!
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.
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();
}
}
ASKER
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
Thanks!!!!
Alex
Could you post your problematic code?
ASKER
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(WhiteboardCon text.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
Imagen-3.png
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);
}
Imagen-2.pngImagen-3.png
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.
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");
}
}
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();
}
}
ASKER
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
ex2.bmp
ex3.bmp
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");
}
}
ex1.bmpex2.bmp
ex3.bmp
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thomas4019, your solution is exactly what I need. Thank you!
What problems?