【问题标题】:Wrap image to Jframe将图像包装到 Jframe
【发布时间】:2017-10-23 06:08:27
【问题描述】:

我试图让我的 Jframe 与我的图像尺寸完全匹配,这样当我尝试通过绘制一个矩形来获取一个区域的 Rectangle2D 坐标时,它会给我它的真实坐标出现在实际图像上。

此解决方案的目标是将 PDF 转换为图像,使用可视映射器识别特定区域,然后使用 PDFBox (PDFTextStripperbyArea) 提取该区域。

以下代码给出的坐标不是提取所需区域的坐标。

这是代码:

    public class PDFVisualMapper extends JFrame {

    BufferedImage image = null;

    public static void main(String[] args) throws IOException {
        new PDFVisualMapper();
    }

    public PDFVisualMapper() throws IOException {
        this.setSize(1700, 2200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.add(new PaintSurface(), BorderLayout.CENTER);
        this.setVisible(true);
    }

    private class PaintSurface extends JComponent {
        ArrayList<Shape> shapes = new ArrayList<Shape>();

        Point startDrag, endDrag;

        public PaintSurface() throws IOException {
            image = ImageIO.read(new File("C:\\Users\\Rusty\\Desktop\\temp\\Test_PDF-1.png"));
            if ( image != null ) {
                Dimension size = new Dimension(image.getWidth(null), image.getHeight(null));
                setPreferredSize(size);
                setMinimumSize(size);
                setMaximumSize(size);
                setSize(size);
                setLayout(null);
            }

            this.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    startDrag = new Point(e.getX(), e.getY());
                    endDrag = startDrag;
                    repaint();
                }

                public void mouseReleased(MouseEvent e) {
                    Shape r = makeRectangle(startDrag.x, startDrag.y, e.getX(), e.getY());
                    shapes.add(r);
                    startDrag = null;
                    endDrag = null;
                    repaint();
                }
            });

            this.addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent e) {
                    endDrag = new Point(e.getX(), e.getY());
                    repaint();
                }
            });
        }

        private void paintBackground(Graphics2D g2) {
            g2.setPaint(Color.LIGHT_GRAY);
            for (int i = 0; i < getSize().width; i += 10) {
                Shape line = new Line2D.Float(i, 0, i, getSize().height);
                g2.draw(line);
            }

            for (int i = 0; i < getSize().height; i += 10) {
                Shape line = new Line2D.Float(0, i, getSize().width, i);
                g2.draw(line);
            }

        }

        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
             paintBackground(g2);
            Color[] colors = { Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.RED, Color.BLUE, Color.PINK };
            int colorIndex = 0;
             g2.drawImage(image, null, 0, 0);

            g2.setStroke(new BasicStroke(2));
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f));

            for (Shape s : shapes) {
                g2.setPaint(Color.BLACK);
                g2.draw(s);
                g2.setPaint(colors[(colorIndex++) % 6]);
                g2.fill(s);
            }

            if (startDrag != null && endDrag != null) {
                g2.setPaint(Color.LIGHT_GRAY);
                Shape r = makeRectangle(startDrag.x, startDrag.y, endDrag.x, endDrag.y);
                g2.draw(r);
                System.out.println(r.getBounds2D());
            }
        }
    }

    private Rectangle2D.Float makeRectangle(int x1, int y1, int x2, int y2) {
        return new Rectangle2D.Float(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
    }

}

有人可以帮忙吗?

【问题讨论】:

  • 想要的结果是什么?一个和图片大小一样的JFrame?
  • 没错,是的,相同的尺寸。理论上,如果框架和图像大小相同,该方法给出的区域坐标提取应该与实际图像区域坐标匹配
  • Don't use setPreferredSize() when you really mean to override getPreferredSize();当你然后pack() 封闭Window,它将是正确的大小。
  • @trashgod,我将如何在上面的代码中实现它?我是 Jframe 的新手,所以现在我有点困惑
  • 下面的示例隐式执行此操作,因为标签的首选大小是 ImageIcon; pack() 相应地工作。

标签: java swing pdf jframe


【解决方案1】:

这可能更简单:在内容窗格中使用JLabel,使用FlowLayout

import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class WarpImage {

    public static void main(String[] args) throws IOException {

        displayImage();
    }

    private static void displayImage() throws IOException{

        URL url = new URL("http://www.digitalphotoartistry.com/rose1.jpg");
        BufferedImage image = ImageIO.read(url);
        ImageIcon icon= new ImageIcon(image);
        JFrame frame=new JFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        JLabel lbl= new JLabel();
        lbl.setIcon(icon);
        frame.add(lbl);
        frame.pack();
        //check size :
        Rectangle bounds = lbl.getBounds();
        System.out.println(bounds.getWidth() +"-"+ bounds.getHeight());
        frame.setVisible(true);
    }
}

【讨论】:

  • 我试过了,看起来不错,但是 jframe 比我的屏幕大。无论如何我可以动态调整jframe的大小,以便如果我把它变小图像仍然适合?
  • 按照here的建议,您可以在pack()之后调用setSize()放大框架。
  • @RustyShackleford 你想让JFrame 比图片小吗?
  • 我只是希望能够看到整个图像,以便识别要提取的区域。我知道这个 Jframe 完全适合图像,这是我在原始问题中提出的问题,但我需要能够看到所有图像。基本上,我正在尝试实现这里讨论的解决方案> dzone.com/articles/visual-mapper-for-pdf-data-extraction
  • 如果问题已得到解答:考虑为其他问题发布新帖子。
【解决方案2】:

我试图让我的 Jframe 与我的图像尺寸完全匹配,这样当我尝试通过绘制一个矩形来获取一个区域的 Rectangle2D 坐标时,它会给我它的真实坐标出现在实际图像上。

然后您自己绘制图像。为什么?因为像 JLabel 这样的组件有自己的内部布局机制,如果图像对于组件大小来说太大或太小,您无法确定图像在 in 中的偏移量。

类似这样的东西,例如:

public class ImagePane extends JPanel {

    private BufferedImage img;

    public ImagePane(BufferedImage img) {
        this.img = img;
    }

    @Override
    public Dimension getPreferredSize() {
        return img == null ? new Dimension(0, 0) : new Dimension(img.getWidth(), img.getHeight());
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            Graphics2D g2 = (Graphics2D) g.create();
            g2.drawImage(img, 0, 0, this);
            g2.dispose();
        }
    }
}

这会将图像放置在组件的左上角,因此如果由于某种原因调整大小,图像将始终位于左上角。坦率地说,生成偏移量以使图像居中并不难,然后组件的后代可以使用它来计算根据需要调整自己的输出所需的偏移量

【讨论】:

    猜你喜欢
    • 2013-08-04
    • 2013-12-17
    • 2014-08-06
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 2013-03-29
    相关资源
    最近更新 更多