问题
I want to zoom image in when left mouse is click and out when right mouse is click, This is the easy part. The portion of image after zoom I want to show is where the mouse is.
e.g an image of car and my mouse position is on car wheel the image should zoom but the focus should remain on car. That's what is tired so far.
package paractice;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Zoom extends JPanel implements ActionListener, MouseListener, MouseMotionListener{
private static final long serialVersionUID = 1L;
private JLabel imageAdujuster = new JLabel();
private JPanel panel = new JPanel();
private JScrollPane pane = new JScrollPane();
private JButton zoomIn = new JButton("Zoom IN");
private JButton zoomOut = new JButton("Zoom Out");
private Point point;
private BufferedImage image;
private double scale = 1;
/*
* Constructor
*/
public Zoom() {
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.add(zoomOut);
buttonPanel.add(zoomIn);
panel.setLayout(new BorderLayout());
panel.add(imageAdujuster, BorderLayout.CENTER);
pane.setViewportView(panel);
pane.setAutoscrolls(true);
setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
zoomOut.addActionListener(this);
zoomIn.addActionListener(this);
imageAdujuster.addMouseListener(this);
imageAdujuster.addMouseMotionListener(this);
}
private void getImage(String imagePath){
try {
File imageFile = new File(imagePath);
image = ImageIO.read(imageFile);
setImage(image);
}catch(Exception e){
System.out.println("Image file not found. "+ e.getMessage());
}
}
private void setImage(Image image) {
imageAdujuster.setIcon(new ImageIcon(image));
}
private BufferedImage getScaledImage(double scale) {
int w = (int)(scale*image.getWidth());
int h = (int)(scale*image.getHeight());
BufferedImage bi = new BufferedImage(w, h, image.getType());
Graphics2D g2 = bi.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
g2.drawRenderedImage(image, at);
g2.dispose();
return bi;
}
public void zoomOut(Point point) {
setImage(getScaledImage(scale * 0.9));
Point pos = pane.getViewport().getViewPosition();
int newX = (int)(point.x*(0.9f - 1f) + 0.9f*pos.x);
int newY = (int)(point.y*(0.9f - 1f) + 0.9f*pos.y);
pane.getViewport().setViewPosition(new Point(newX, newY));
this.pane.revalidate();
this.pane.repaint();
}
/**
*
*/
public void zoomIn(Point point) {
setImage(getScaledImage(scale * 1.1f));
Point pos = pane.getViewport().getViewPosition();
int newX = (int)(point.x*(1.1f - 1f) + 1.1f*pos.x);
int newY = (int)(point.y*(1.1f - 1f) + 1.1f*pos.y);
pane.getViewport().setViewPosition(new Point(newX, newY));
this.pane.revalidate();
this.pane.repaint();
}
public static void main(String args[]) {
JFrame frame = new JFrame();
Zoom zoom = new Zoom();
zoom.getImage("C:\\Users\\abcd1\\Pictures\\picture.jpg");
frame.getContentPane().add(zoom);
frame.pack();
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == zoomIn) {
scale ++;
zoomIn(point);
}
if(e.getSource() == zoomOut) {
scale --;
zoomOut(point);
}
}
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)) {
scale += 1;
zoomIn(point);
}
if(SwingUtilities.isRightMouseButton(e)) {
scale -= 1;
zoomOut(point);
}
}
public void mouseMoved(MouseEvent e) {
PointerInfo info = MouseInfo.getPointerInfo();
point = info.getLocation();
System.out.println("point x is "+point.x +" point y is "+point.y);
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
public void mouseDragged(MouseEvent e) {}
}
回答1:
To zoom and change JScrollPane
position I changed two methods and added scaleAndZoom(double)
:
public void zoomOut(Point point) {
scaleAndZoom( scale * 0.9f);
}
public void zoomIn(Point point) {
scaleAndZoom( scale * 1.1f);
}
private void scaleAndZoom(double scale) {
setImage(getScaledImage(scale));
//calculation is not quiet accurate. Need to improve
//see Aqeel Haider comment
int moveX = (int) ((scale* point.x) - point.x ) ;
int moveY = (int) ((scale* point.y) - point.y ) ;
Rectangle view = pane.getViewport().getViewRect();
view.setBounds(view.x+moveX,view.y+moveY, view.width, view.height);
imageAdujuster.scrollRectToVisible(view);
}
回答2:
I didn't use the ScrollPane. Here my Solution.
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
int w = this.getWidth();
int h = this.getHeight();
if(orginalImage == null )return;
int imageWidth = orginalImage.getWidth();
int imageHeight = orginalImage.getHeight();
BufferedImage bi = new BufferedImage(
(int)(imageWidth*scale),
(int)(imageHeight*scale),
orginalImage.getType());
Graphics2D g2 = bi.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.translate(point.x, point.y);
g2d.scale(scale, scale);
g2d.translate(-point.x, -point.y);
//g2d.translate(-w/2, -h/2);
g2d.drawImage(orginalImage, 0, 0, w, h, null);
this.setPreferredSize(new Dimension(orginalImage.getWidth(), orginalImage.getHeight()));
if(selection == null) return;
g2d.setStroke(new BasicStroke(2));
g2d.setColor(Color.RED);
g2d.draw(selection);
resizeImage();
}`
Where point.x is and point.y is the mouse position. also check translate method of the Graphics.
https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#translate(int,%20int)
来源:https://stackoverflow.com/questions/46144737/zoom-image-in-and-out-also-change-jscrollpane-according-to-mouse-position