2014-12-07 4 views
0

기본적으로 비디오에서 실시간으로 BufferedImages로 이미지를 추출하고 처리 후 JFrame에 표시합니다. 안타깝게도 나는 스윙이 매우 좋지 않아 이미지가 의도 한대로 JFrame에 표시되는 동안 모든 새로운 이미지 (초당 24 개)마다 새로운 JFrame이 생성됩니다.BufferedImage에 액세스하여 JFrame 구성 요소를 업데이트하십시오.

내가 가진 GUI로 BufferedImage의를 보내

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);   
} 
: 그들은 본질적으로 JFrame의 내부 JPanel의 내부 현재 이미지를 포함하는 JLabel의 내 GUI 클래스에 의해 수신

UserInterface.main(currentFrame); 

누구나이 문제를 해결하여 모든 이미지를 동적으로 표시 할 수있는 JFrame이 1 개만 표시되도록 조언 할 수 있습니까?

+0

'contentPane.setLayout (null);'Java GUI는 다른 OS, 화면 크기, 화면 해상도 등에서 작동해야합니다. 따라서 픽셀 완전 레이아웃에 도움이되지 않습니다. 대신 레이아웃 관리자 또는 [조합] (http://stackoverflow.com/a/5630271/418556)과 [공백] 레이아웃 채우기 및 테두리 (http://stackoverflow.com/a/17874718/)를 사용하십시오. 418556). –

답변

1

imageLabelUserInterface의 클래스 멤버로 리팩토링하고 모든 프레임마다 ImageIcon을 업데이트해야합니다. 그러나 너무 느려서 프레임 이미지를 그리기 위해 paintComponent(Graphics)을 재정의하는 자체 패널 클래스를 만들고자 할 것입니다. 마지막으로 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'는 배경을 칠하지만,'Graphics' 컨텍스트를 지우지 않으면 다른 페인트 이슈가 나타날 수 있습니다. 실제로는 원하지 않습니다. * "그리고 fillRect를 사용하여 캔버스를 지우는 것이 super.paintComponent에 위임하는 것보다 훨씬 빠릅니다"* - 기본적으로 모두 super.paintComponent가 있기 때문에 메트릭이 있습니까? – MadProgrammer