2014-12-07 4 views
0

В основном, я извлекаю изображения из видео в реальном времени как BufferedImages и отображаю их в JFrame после обработки. К сожалению, я очень плохо отношусь к качелям, поэтому, пока изображения появляются в JFrame, как предполагалось, он генерирует новый JFrame для каждого нового изображения (24 в секунду).Доступ к BufferedImages для обновления компонентов JFrame

я посылаю BufferedImages к ГИП с:

UserInterface.main(currentFrame); 

Где они получили мой GUI класса, который является по существу JLabel, содержащий текущее изображение внутри JPanel внутри JFrame:

public class UserInterface extends JFrame { 
private JPanel contentPane; 

public static void main(BufferedImage inputImage) throws IOException 
{ 
    UserInterface frame = new UserInterface(inputImage); 
    frame.setVisible(true); 
} 

public UserInterface(BufferedImage inputImage) throws IOException 
{  
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    setBounds(50, 50, 1024, 768); 
    contentPane = new JPanel(); 
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    setContentPane(contentPane); 
    contentPane.setLayout(null); 

    JLabel imageLabel = new JLabel(new ImageIcon(inputImage)); 
    add(imageLabel); 
    imageLabel.setBounds(11, 60, 480, 360); 
    contentPane.add(imageLabel);   
} 

Может ли кто-нибудь посоветовать, как разбить это, чтобы создать только 1 JFrame, в котором я могу отображать все изображения динамически?

+0

'contentPane.setLayout (null);' Java GUIs должны работать с различными ОС, размером экрана, разрешением экрана и т. Д. Таким образом, они не способствуют идеальной компоновке пикселей. Вместо этого используйте диспетчеры макетов или [их комбинации] (http://stackoverflow.com/a/5630271/418556), а также макет и границы для [пробела] (http://stackoverflow.com/a/17874718/ 418556). –

ответ

1

Вам необходимо сделать рефакторинг imageLabel членом класса UserInterface и обновить его подставку ImageIcon каждый кадр. Однако это может быть слишком медленным, и в этом случае вы захотите создать свой собственный класс панели, который переопределяет paintComponent(Graphics), чтобы нарисовать изображение рамки. Наконец, вы должны вручную вызвать repaints для этой панели, вызвав paintImmediately(getBounds()). Что-то по следующим направлениям должно работать:

public class VideoPanel extends JPanel { 
    private BufferedImage frame; 

    public VideoPanel() { 

    } 

    public void setFrame(BufferedImage image) { 
     this.frame = image; 
     paintImmediately(getBounds()); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if(frame == null) return; 
     int width = frame.getWidth(); 
     int height = frame.getHeight(); 
     Dimension boundary = getSize(); 
     // Scale image dimensions with aspect ratio to fit inside the panel 
     int bwidth; 
     int bheight = ((bwidth = boundary.width) * height)/width; 
     if (bheight > boundary.height) { 
      bwidth = ((bheight = boundary.height) * width)/height; 
     } 
     // Center it in the space given 
     int x = Math.abs(boundary.width - bwidth)/2; 
     int y = Math.abs(boundary.height - bheight)/2; 
     g.drawImage(frame, x, y, bwidth, bheight, null); 
    } 
} 

Вы также, вероятно, хотите, чтобы очистить фон панели, прежде чем рисовать на ней, чтобы предотвратить артефакты визуализации.

+0

Ваш метод paintComponent разрушает цепочку окраски. –

+0

@HovercraftFullOfEels Я обновил свой ответ, чтобы включить супер-вызов paintComponent. Моя (возможно, необоснованная) логика не включала в себя то, что на видеопанете, вероятно, никогда не будет детей, и очистка холста самостоятельно (с помощью fillRect) будет намного быстрее, чем делегирование super.paintComponent. – Xyene

+0

@Nox 'paintComponent' рисует фон, но неспособность очистить контекст« Графика »может привести к появлению других артефактов краски, которые вам действительно не нужны. * "и очистка холста самостоятельно (с помощью fillRect) довольно немного быстрее, чем делегирование super.paintComponent" * - У вас есть показатели для этого, потому что по существу это все 'super.paintComponent', по умолчанию – MadProgrammer

 Смежные вопросы

  • Нет связанных вопросов^_^