简体   繁体   English

图像平移和缩放

[英]Image Pan and Zooming

I want to display an image to zoom in and out and can be shifted. 我想显示一个图像来放大和缩小,可以移动。 I have the script below, but it can not be shifted. 我有下面的脚本,但它无法移动。 how to fix it. 如何解决它。

the code : 编码 :

package dispertasih;

import static dispertasih.PanPanel.startX;
import java.awt.*;  
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.*;  
import java.awt.image.BufferedImage;  
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;  
import javax.swing.event.*;  

public class PadAndZoom implements ChangeListener {  
    BufferedImage image;  
    PanPanel label;  

    public void stateChanged(ChangeEvent e) {  
        int value = ((JSlider)e.getSource()).getValue();  
        double scale = value/200.0;  
        BufferedImage scaled = getScaledImage(scale);  
       label = new PanPanel(scaled);  
        label.revalidate();  // signal scrollpane  
    }  

    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;  
    }  

    private PanPanel getContent() {  
        createAnImage();  
        label = new PanPanel(image);  
        //label.setHorizontalAlignment(JLabel.CENTER);  
        return label;  
    }  

    private void createAnImage() {  
        int w = 500;  
        int h = 500;  
        int type = BufferedImage.TYPE_INT_RGB; // many options  
        try {
            image = ImageIO.read(PadAndZoom.class.getResource("/tampilan/background5.jpg"));
        } catch (IOException ex) {
            Logger.getLogger(PadAndZoom.class.getName()).log(Level.SEVERE, null, ex);
        }


    }  

    private JSlider getControl() {  
        JSlider slider = new JSlider(JSlider.HORIZONTAL, 50, 200, 50);  
        slider.setMajorTickSpacing(50);  
        slider.setMinorTickSpacing(10);  
        slider.setPaintTicks(true);  
        slider.setPaintLabels(true);  
        slider.addChangeListener(this);  
        return slider;          
    }  

    public static void main(String[] args) {  
        PadAndZoom app = new PadAndZoom();  
        JFrame f = new JFrame();  
        JButton b = new JButton();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        f.getContentPane().add(new JScrollPane(app.getContent()));  

        //f.getContentPane().add(new JButton("tessss"));
        f.getContentPane().add(app.getControl(), "Last");  
        f.setSize(400, 400);  
        f.setLocation(200,200);  
        f.setVisible(true);  
    }  
}  
class PanPanelX extends JPanel {

private int x, y;
private int width = 800, height = 800;
BufferedImage img;
private final static RenderingHints textRenderHints = new    RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
private final static RenderingHints imageRenderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
private final static RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
static int startX, startY;

public PanPanelX(BufferedImage img) {
    x = 20;
    y = 20;
    this.img = img;

    addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent me) {
            super.mousePressed(me);
            startX = me.getX();
            startY = me.getY();
        }
    });

    addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent me) {
            super.mouseDragged(me);

            if (me.getX() < startX) {//moving image to right
                x -= 2;
            } else if (me.getX() > startX) {//moving image to left
                x += 2;
            }

            if (me.getY() < startY) {//moving image up
                y -= 2;
            } else if (me.getY() > startY) {//moving image to down
                y += 2;
            }
            repaint();
        }
    });
}

@Override
protected void paintComponent(Graphics grphcs) {
    super.paintComponent(grphcs);
    Graphics2D g2d = (Graphics2D) grphcs;

    //turn on some nice effects
    applyRenderHints(g2d);

    g2d.drawImage(img, x, y, null);
}

@Override
public Dimension getPreferredSize() {
    return new Dimension(width, height);
}

public static void applyRenderHints(Graphics2D g2d) {
    g2d.setRenderingHints(textRenderHints);
    g2d.setRenderingHints(imageRenderHints);
    g2d.setRenderingHints(renderHints);
}
}

i think on : 我想:

public void stateChanged(ChangeEvent e) {  
        int value = ((JSlider)e.getSource()).getValue();  
        double scale = value/200.0;  
        BufferedImage scaled = getScaledImage(scale);  
       label = new PanPanel(scaled);  
        label.revalidate();  // signal scrollpane  
    } 

there are mistakes, but I've stuck fixing it.... 有错误,但我坚持修复它....

thank you ... 谢谢 ...

The problem is, the reference of the image that is displayed on the screen is not the same as the image you are creating when you resize it... 问题是,屏幕上显示的图像的参考与您调整大小时所创建的图像不同...

You create PanPanel by using... 您可以使用...创建PanPanel

BufferedImage scaled = getScaledImage(scale);
label = new PanPanel(scaled);

getScaledImage creates a new image each time it is called, based on the original image. getScaledImage在每次调用时都会根据原始图像创建一个新图像。

BufferedImage bi = new BufferedImage(w, h, image.getType());

This means, that the image in PadAndZoom is not the same as the one in PanPanel , so any changes you make to image or any new scaled instances will never be painted because PanPanel knows nothing about them... 这意味着, PadAndZoom中的imagePadAndZoom中的image PanPanel ,因此您对image或任何新的缩放实例所做的任何更改都将永远不会被绘制,因为PanPanel对它们一无所知......

Now, in stateChanged , instead of updating the instance of PanPanel that you already have, you create a new instance of it...and that's it...it's never added to any displayable component, so it will never appear on the screen. 现在,在stateChanged ,不是更新已经拥有的PanPanel实例,而是创建它的新实例......就是这样......它永远不会添加到任何可显示的组件中,因此它永远不会出现在屏幕上。

Instead, in your PanPanel , you need to supply some way for the stateChanged method to pass the scaled instance of the image to it... 相反,在你的PanPanel ,你需要为stateChanged方法提供一些方法来将图像的缩放实例传递给它...

public void setImage(BufferedImage img) {
    this.img = img;
    revalidate();
    repaint();
}

Then in your stateChanged method you can do... 然后在你的stateChanged方法中你可以做...

int value = ((JSlider) e.getSource()).getValue();
double scale = value / 200.0;
BufferedImage scaled = getScaledImage(scale);
label.setImage(scaled);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM