refreshing/reloading Java 应用程序 (Swing) 中的图像
refreshing/reloading image in a Java Application (Swing)
我编写了一个程序来从网络摄像头拍摄快照(通过 OpenCV)并将其保存到项目中:
Colordetection
|__src
| |
| main.java
|
| Snapshot.png
现在我想刷新快照,每次重新拍摄并重新绘制它。
String imgText = "Snapshot.png";
JPanel panelScreenshot = new JPanel();
panelScreenshot.setBorder(new TitledBorder(null, "Screenshot", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panelScreenshot.setBounds(10, 11, 667, 543);
panelDisplay.add(panelScreenshot);
panelScreenshot.setLayout(null);
JLabel lblScreenshot = new JLabel();
lblScreenshot.setIcon(new ImageIcon(imgText));
lblScreenshot.setBounds(10, 21, 640, 480);
panelScreenshot.add(lblScreenshot);
JButton btnScreenshot = new JButton("Screenshot");
btnScreenshot.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
VideoCapture cap = new VideoCapture(0);
if(!cap.isOpened()){
System.out.println("Webcam not Found");
}
else
{
System.out.println("Found Webcam:" + cap.toString());
Mat frame = new Mat();
cap.retrieve(frame);
try {
Thread.sleep(500);
Highgui.imwrite("Snapshot.png", frame);
lblScreenshot.repaint();
}
catch (Exception e1) {
e1.printStackTrace();
}
cap.release();
}
}
});
问题是,它并没有像我想要的那样repaint/refresh,只有当我重新启动程序时,新的屏幕截图才会出现。
我也尝试过:
ImageIcon icon = new ImageIcon(main.class.getResource("Snapshot.png"));
并更改了路径等,但没有帮助。
有人知道吗?
谢谢。
永远永远不要在美国东部时间打电话给 Thread.sleep
。这冻结了你的整个 UI。 Swing 是单线程的,所以如果你让那个线程休眠,整个 UI 就会被冻结
话虽如此,原因是图标只加载了一次。磁盘上的实际图像发生变化并不重要。您需要致电
lblScreenshot.setIcon(new ImageIcon(imgText));
在替换光盘上的图像后再次进行。这将重新加载图像。
图像由 ImageIcon 缓存,因此您可以:
- 刷新图像,强制重新加载
- 使用 ImageIO 重新读取图像
简单示例:
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);
// This works using ImageIO
// imageLabel.setIcon( new ImageIcon(ImageIO.read( new File(imageName) ) ) );
// Or you can flush the image
ImageIcon icon = new ImageIcon(imageName);
icon.getImage().flush();
imageLabel.setIcon( icon );
}
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 class 来动态重新生成图像。
我编写了一个程序来从网络摄像头拍摄快照(通过 OpenCV)并将其保存到项目中:
Colordetection
|__src
| |
| main.java
|
| Snapshot.png
现在我想刷新快照,每次重新拍摄并重新绘制它。
String imgText = "Snapshot.png";
JPanel panelScreenshot = new JPanel();
panelScreenshot.setBorder(new TitledBorder(null, "Screenshot", TitledBorder.LEADING, TitledBorder.TOP, null, null));
panelScreenshot.setBounds(10, 11, 667, 543);
panelDisplay.add(panelScreenshot);
panelScreenshot.setLayout(null);
JLabel lblScreenshot = new JLabel();
lblScreenshot.setIcon(new ImageIcon(imgText));
lblScreenshot.setBounds(10, 21, 640, 480);
panelScreenshot.add(lblScreenshot);
JButton btnScreenshot = new JButton("Screenshot");
btnScreenshot.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
VideoCapture cap = new VideoCapture(0);
if(!cap.isOpened()){
System.out.println("Webcam not Found");
}
else
{
System.out.println("Found Webcam:" + cap.toString());
Mat frame = new Mat();
cap.retrieve(frame);
try {
Thread.sleep(500);
Highgui.imwrite("Snapshot.png", frame);
lblScreenshot.repaint();
}
catch (Exception e1) {
e1.printStackTrace();
}
cap.release();
}
}
});
问题是,它并没有像我想要的那样repaint/refresh,只有当我重新启动程序时,新的屏幕截图才会出现。
我也尝试过:
ImageIcon icon = new ImageIcon(main.class.getResource("Snapshot.png"));
并更改了路径等,但没有帮助。
有人知道吗?
谢谢。
永远永远不要在美国东部时间打电话给 Thread.sleep
。这冻结了你的整个 UI。 Swing 是单线程的,所以如果你让那个线程休眠,整个 UI 就会被冻结
话虽如此,原因是图标只加载了一次。磁盘上的实际图像发生变化并不重要。您需要致电
lblScreenshot.setIcon(new ImageIcon(imgText));
在替换光盘上的图像后再次进行。这将重新加载图像。
图像由 ImageIcon 缓存,因此您可以:
- 刷新图像,强制重新加载
- 使用 ImageIO 重新读取图像
简单示例:
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);
// This works using ImageIO
// imageLabel.setIcon( new ImageIcon(ImageIO.read( new File(imageName) ) ) );
// Or you can flush the image
ImageIcon icon = new ImageIcon(imageName);
icon.getImage().flush();
imageLabel.setIcon( icon );
}
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 class 来动态重新生成图像。