繁体   English   中英

如何初始化取决于组件大小的图像抓取?

[英]How can I initialize an image grab that depends on the size of the component?

我正在Java Swing中创建一个程序,但是遇到了问题。 该程序有两个图像。 图像之一是完整图像,并显示在图像导航器中。 另一个图像是整个图像的放大部分,并显示在另一个组件中。

每当我在ZoomedImage容器中查看的部件更新时,我的主类中都会出现以下内容:

BufferedImage zoom = imageNavigator.getZoomedImage();
((ZoomedImage)container.getTopComponent()).updatePanel(zoom);

哪个调用:

public BufferedImage getZoomedImage(){
    BufferedImage img = image.getSubimage((int)(startX/scaleX), (int)(startY/scaleY), (int)(image.getWidth()*percentViewWidth), (int)(image.getHeight()*percentViewHeight));
    BufferedImage copyOfImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics g = copyOfImage.createGraphics();
    g.drawImage(img, 0, 0, null);
    return copyOfImage;
}

初始化组件时,我还会调用类似的代码。

startX / Y是显示放大区域的方框的起点。 ScaleX / Y与显示的图像大小和显示图像的组件的大小之间的比例有关。 percentViewWidth / Height是缩放信息的一部分。

打包所有组件后,该功能可以正常工作。 每当我更改要查看的原始图像的哪一部分时,缩放后的图像都会更新得很好。 问题在于,要做到这一点,我必须依赖于保存主图像的组件的大小,以便可以获取图像的正确部分。 首次初始化时,大小为0,所以我无法抓住正确的部分。 如何确定大小后立即更新图像?

如果我正确理解问题,那么您的方法会有些落后。 与其让ImageNavigator告诉ZoomedImage绘制哪个子图像,不如让ZoomedImage在绘制时询问ImageNavigator(通过重写ZoomedImage的paintComponent方法)。 当ZonedImage进行绘画时,它将完全摆在屏幕上,并且知道其大小,因此不会有问题。

另外,让ZoomedImage维护整个图像和显示区域的坐标,以便它将具有绘制自身所需的完整信息。 当用户与ImageNavigator交互时,它可以调用ZoomedImage来设置显示区域的坐标。

为了更加具体,这是第二种方法的一个小例子。 为简便起见,我没有创建“ ZoomedImage”类,而是使用了包含图像JLabel的JScrollPane,但它确实可以完成工作。 右侧是ImageNavigator,它调用“ ZoomedImage组件”(实际上是滚动窗格的视口)以获取并设置显示区域的坐标。 它绘制一个红色矩形突出显示该部分。 您可以使用滚动条,导航器或调整窗口大小来调整显示的区域。 没什么太复杂了,但希望它包含一些有用的见解:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

class ImageNavigatorExample {
    public static void main(String[] args) throws Throwable {
        File imageFile = new File( // change file to one you have!
            "Shallow Waters in the South Pacific.jpg");
        BufferedImage image = javax.imageio.ImageIO.read(imageFile);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        JScrollPane imageScroller = new JScrollPane(new JLabel(new ImageIcon(image)));
        imageScroller.setPreferredSize(new Dimension(640, 480));
        frame.add(imageScroller);
        frame.add(new ImageNavigator(image, imageScroller.getViewport()), BorderLayout.EAST);
        frame.pack();
        frame.setVisible(true);
    }


    private static class ImageNavigator extends JPanel {
        private final BufferedImage image;
        private final JViewport viewport;

        public ImageNavigator(BufferedImage image, final JViewport viewport) {
            this.image = image;
            this.viewport = viewport;
            viewport.addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    repaint();
                }
            });
            MouseAdapter mouseAdapter = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    int xImage = Math.round(e.getX() / scale());
                    int yImage = Math.round(e.getY() / scale());

                    viewport.setViewPosition(new Point(
                        Math.max(0, xImage - viewport.getExtentSize().width / 2),
                        Math.max(0, yImage - viewport.getExtentSize().height / 2)));
                }

                @Override
                public void mouseDragged(MouseEvent e) {
                    mousePressed(e);
                }
            };
            this.addMouseListener(mouseAdapter);
            this.addMouseMotionListener(mouseAdapter);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(150, image.getWidth() * 150 / image.getHeight());
        }

        private float scale() {
            return (float)this.getWidth() / image.getWidth();
        }

        @Override
        public void paintComponent(Graphics g1) {
            super.paintComponent(g1);

            Graphics2D g = (Graphics2D)g1.create();
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.scale(scale(), scale());
            g.drawImage(image, 0, 0, null);

            g.setColor(Color.red);
            g.setStroke(new BasicStroke(scale()));
            g.draw(viewport.getViewRect());
        }
    }
}

看起来像什么:

截图

暂无
暂无

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

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