【问题标题】:Captured image do not get detected by the java program [closed]java程序未检测到捕获的图像[关闭]
【发布时间】:2015-04-22 20:10:37
【问题描述】:

在我的 java 程序中,我正在制作一个 GUI,它应该在单击 JButton 时在 JPanel 中显示捕获的图像。

下面是我创建的用于渲染捕获的图像的自定义 ImagePanel 类。

public class ImagePanel extends JPanel {
    private static final long serialVersionUID = 1L;
    private BufferedImage image;

    public ImagePanel() {
        try {
            File f = new File("capture.jpg");
            f.exists();  //this is returning false here, don't no why ?
            image = ImageIO.read(f); 
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    }
}

点击 JButton,在 ActionListener 中,我正在执行以下操作

@Override
    public void actionPerformed(ActionEvent e) {
        String s = e.getActionCommand();
        System.out.println(s);
        if (s.equals("Capture Image")) {
            //Here calling a script to capture the image.
            try {
                Process proc = Runtime.getRuntime().exec("./capture.sh");
                Thread.sleep(2000);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            ImagePanel  panel = new ImagePanel();
            containerPanel.add(panel);
            containerPanel.revalidate();
            containerPanel.repaint();
            .....

不过,我的程序仍然无法检测到捕获的图像并显示它。但是当我下次单击 JButton 时,它会显示以前捕获的图像。

即使经过大量的努力,也无法发现问题。任何帮助表示赞赏。 谢谢!

【问题讨论】:

  • 你确定你能进去吗?那个字符串比较看起来很糟糕。为什么你不使用 java 8 和 lambda button.addActionListener((e) -> { // your code}) ?
  • @Lukino 他的字符串比较没有问题。事实上,我想说使用.equals() 比一般的 lambda 好得多——如果一个不使用 Java 8 并且对 lambdas 一无所知的开发人员看到它怎么办?他会完全糊涂的。
  • @Aify - 然后我建议进入。这就像如果还有蜡烛,为什么要用电来照明房间?当您需要重构时,基于字符串常量的行为并不漂亮。至少把它放到 Enum 中,所以常量在 1 位。
  • 那么你在哪里实际创建图像???发布一个正确的SSCCE 来证明问题。人们试图只用一半的信息来回答。您的 ActionListener 假定图像已经创建。
  • 在论坛发帖完全不需要 lambda 表达式。您希望尽可能多的人能够阅读/执行您的代码。

标签: java swing events jpanel actionlistener


【解决方案1】:

你说:

File f = new File(capture.jpg); // ****this compiles without quotes?????
f.exists();  //this is returning false
image = ImageIO.read(f);

这可能是错误的,因为您的路径错误。请记住,使用 Files 时,路径是相对于 user.dir 路径的。要查看用户目录是什么,只需打印出来:

System.out.println(System.getProperty("user.dir"));

最好使用资源而不是文件,...

InputStream iStream = getClass().getResourceAsStream("capture.jpg");
image = ImageIO.read(iStream);

使用资源时,路径将相对于类路径——类文件的位置,而不是用户目录。

【讨论】:

  • 你们都缺少引号。但这听起来是对的。
  • @Lukino:但是我的 cmets 它不应该编译!
  • 哦,抱歉,您刚刚复制了它,但是您在 getResourceAsStream 中使用了引号。撤回我的一半评论;-)
  • @Lukino my capture.jpg 与程序位于同一目录中。我还需要给出完整的路径吗??
  • @Bruce_Wayne:再一次,请像我向您展示的那样使用图像作为资源。
【解决方案2】:

这是一个使用图像不断更新 JLabel 的示例:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;
import javax.imageio.*;
import javax.swing.*;
import java.net.*;

public class ImageReload extends JPanel implements ActionListener
{
    JLabel timeLabel;
    JLabel imageLabel;
    ImageIcon icon = new ImageIcon("timeLabel.jpg");

    public ImageReload()
    {
        setLayout( new BorderLayout() );

        timeLabel = new JLabel( new Date().toString() );
        imageLabel = new JLabel( timeLabel.getText() );

        add(timeLabel, BorderLayout.NORTH);
        add(imageLabel, BorderLayout.SOUTH);

        javax.swing.Timer timer = new javax.swing.Timer(1000, this);
        timer.start();
    }

    public void actionPerformed(ActionEvent e)
    {
        timeLabel.setText( new Date().toString() );

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    String imageName = "timeLabel.jpg";
                    BufferedImage image = ScreenImage.createImage(timeLabel);
                    ScreenImage.writeImage(image, imageName);

                    InputStream iStream = getClass().getResourceAsStream(imageName);
                    imageLabel.setIcon( new ImageIcon(ImageIO.read( iStream ) ) );

                }
                catch(Exception e)
                {
                    System.out.println( e );
                }
            }
        });
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ImageReload() );
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

此示例还需要使用Screen Image 类。

编辑:

它显示之前捕获的图像。

所以我猜问题是您的代码在图像写入之前执行。我对你的相机应用一无所知。

也许您可以使用Process.waitFor() 方法等待进程完成。

或者也许您应该使用 `SwingWorker。

【讨论】:

  • 这是一种不断变化的需求类型问题,总是很难回答。 1+ 为您的尝试。
  • @camickr 感谢您的努力,请注意删除您的答案,我正在考虑删除问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
相关资源
最近更新 更多