我想在单击鼠标左键时放大图像,在单击鼠标右键时放大图像,这是简单的部分。我想要显示的缩放后图像的部分是鼠标所在的位置。
例如,汽车的图像,我的鼠标位置位于车轮上,图像应该缩放,但焦点应保留在汽车上。这就是目前为止比较累的地方。
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) {}
}
最佳答案
为了缩放和更改 JScrollPane
位置,我更改了两种方法并添加了 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);
}
关于java - 放大和缩小图像也会根据鼠标位置更改 JscrollPane,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46144737/