문제

나는있다 jpanel 이를 위해 즉시 생성하는 JPEG 및 PNG 이미지를 추가하고 싶습니다.

내가 지금까지 본 모든 예제 스윙 튜토리얼, 특히 스윙 예제 사용 ImageIcon에스.

이 이미지를 바이트 어레이로 생성하고 있으며 일반적으로 예제에서 사용하는 일반적인 아이콘 (640x480)보다 큽니다.

  1. ImageIcon 클래스를 사용하여 JPANEL에 크기가 크기를 표시하는 데있어 (성능 또는 기타) 문제가 있습니까?
  2. 무엇입니까 보통의 그것을하는 방법?
  3. imageicon 클래스를 사용하지 않고 이미지를 jpanel에 추가하는 방법은 무엇입니까?

편집하다: 튜토리얼과 API에 대한보다 신중한 검토는 ZPANEL에 ImageICon을 직접 추가 할 수 없음을 보여줍니다. 대신, 그들은 이미지를 jlabel의 아이콘으로 설정함으로써 동일한 효과를 달성합니다. 이것은 단지 옳지 않습니다 ...

도움이 되었습니까?

해결책

다음은 내가 수행하는 방법입니다 (이미지를로드하는 방법에 대한 좀 더 많은 정보와 함께) :

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel{

    private BufferedImage image;

    public ImagePanel() {
       try {                
          image = ImageIO.read(new File("image name and path"));
       } catch (IOException ex) {
            // handle exception...
       }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, this); // see javadoc for more info on the parameters            
    }

}

다른 팁

JPANEL을 사용하는 경우 아마도 스윙으로 작업하고있을 것입니다. 이 시도:

BufferedImage myPicture = ImageIO.read(new File("path-to-file"));
JLabel picLabel = new JLabel(new ImageIcon(myPicture));
add(picLabel);

이미지는 이제 스윙 구성 요소입니다. 다른 구성 요소와 마찬가지로 레이아웃 조건이 적용됩니다.

Fred Haslam의 방식은 잘 작동합니다. 그래도 항아리 안에 이미지를 참조하고 싶기 때문에 Filepath에 문제가있었습니다. 이렇게하려면 다음을 사용했습니다.

BufferedImage wPic = ImageIO.read(this.getClass().getResource("snow.png"));
JLabel wIcon = new JLabel(new ImageIcon(wPic));

이 방법을 사용하여로드 해야하는 유한 번호 (약 10) 이미지 만 있으므로 잘 작동합니다. 올바른 상대 필라 패스가 없어도 파일을 얻습니다.

나는 아무 것도 서브 클래스 할 필요가 없다고 생각합니다. jlabel 만 사용하십시오. 이미지를 jlabel로 설정할 수 있습니다. 따라서 jlabel을 조정 한 다음 이미지로 채우십시오. 괜찮아. 이것이 제가하는 방식입니다.

무료에서 jximagepanel 클래스를 사용하여 자신의 구성 요소 서브 클래스를 완전히 롤링하지 않을 수 있습니다. 스윙 렉스 도서관.

다운로드

JLabel imgLabel = new JLabel(new ImageIcon("path_to_image.png"));
  1. 문제가 없어야합니다 (매우 큰 이미지로 가질 수있는 일반적인 문제 외에).
  2. 단일 패널에 여러 이미지를 추가하는 것에 대해 이야기하고 있다면 ImageIcon에스. 단일 이미지의 경우, 나는 사용자 정의 서브 클래스를 만드는 것에 대해 생각할 것입니다. JPanel 그리고 그것을 우선합니다 paintComponent 이미지를 그리는 방법.
  3. (2 참조)

서브 클래스 jpanel- 여기 내 ImagePanel의 추출물이 있습니다. 여기에는 5 개의 위치 중 하나, 상단/왼쪽, 상단/오른쪽, 중간/중간/왼쪽 또는 하단/오른쪽 중 하나에 이미지가 있습니다.

protected void paintComponent(Graphics gc) {
    super.paintComponent(gc);

    Dimension                           cs=getSize();                           // component size

    gc=gc.create();
    gc.clipRect(insets.left,insets.top,(cs.width-insets.left-insets.right),(cs.height-insets.top-insets.bottom));
    if(mmImage!=null) { gc.drawImage(mmImage,(((cs.width-mmSize.width)/2)       +mmHrzShift),(((cs.height-mmSize.height)/2)        +mmVrtShift),null); }
    if(tlImage!=null) { gc.drawImage(tlImage,(insets.left                       +tlHrzShift),(insets.top                           +tlVrtShift),null); }
    if(trImage!=null) { gc.drawImage(trImage,(cs.width-insets.right-trSize.width+trHrzShift),(insets.top                           +trVrtShift),null); }
    if(blImage!=null) { gc.drawImage(blImage,(insets.left                       +blHrzShift),(cs.height-insets.bottom-blSize.height+blVrtShift),null); }
    if(brImage!=null) { gc.drawImage(brImage,(cs.width-insets.right-brSize.width+brHrzShift),(cs.height-insets.bottom-brSize.height+brVrtShift),null); }
    }

JPanel 거의 항상 서브 클래스의 잘못된 클래스입니다. 왜 서브 클래스가 아닌가? JComponent?

약간의 문제가 있습니다 ImageIcon 생성자가 이미지를 읽는다는 점에서. 응용 프로그램 JAR에서로드 할 때 실제로 문제가되지 않지만 네트워크 연결을 통해 잠재적으로 읽을 수있는 경우에 문제가 있습니다. 사용의 AWT 시대의 예가 많이 있습니다 MediaTracker, ImageObserver 그리고 JDK 데모에서도 친구.

나는 내가 작업중 인 개인 프로젝트에서 매우 비슷한 일을하고 있습니다. 지금까지 문제없이 최대 1024x1024의 이미지를 생성했으며 (메모리 제외) 성능 문제없이 매우 빠르게 표시 할 수 있습니다.

JPANEL 서브 클래스의 페인트 방법을 무시하는 것은 과잉이며 필요한 것보다 더 많은 작업이 필요합니다.

내가하는 방식은 다음과 같습니다.

Class MapIcon implements Icon {...}

또는

Class MapIcon extends ImageIcon {...}

이미지를 생성하는 데 사용하는 코드는이 클래스에 있습니다. 나는 Painticon ()이 호출 될 때 BufferedImage를 사용하여 G.DrawImvge (bufferedImage)를 사용합니다. 이렇게하면 이미지를 생성하는 동안 수행 된 깜박임의 양이 줄어들고 스레드를 삭제할 수 있습니다.

다음으로 Jlabel을 확장합니다.

Class MapLabel extends Scrollable, MouseMotionListener {...}

내 이미지를 스크롤 창에 넣고 싶기 때문입니다. 즉, 이미지의 일부를 표시하고 사용자가 필요에 따라 스크롤되도록하기 때문입니다.

그래서 나는 jscrollpane을 사용하여 mapicon 만 포함하는 maplabel을 고정합니다.

MapIcon map = new MapIcon (); 
MapLabel mapLabel = new MapLabel (map);
JScrollPane scrollPane = new JScrollPane();

scrollPane.getViewport ().add (mapLabel);

그러나 시나리오를 위해 (매번 전체 이미지를 표시하십시오). 메이플 라벨을 상단 jpanel에 추가하고 이미지의 전체 크기 (getPreferredsize ()를 재정의함으로써)로 크기를 크기로 크기를 조정해야합니다.

프로젝트 디렉토리에서 소스 폴더를 만듭니다.이 경우 이미지라고 불렀습니다.

JFrame snakeFrame = new JFrame();
snakeFrame.setBounds(100, 200, 800, 800);
snakeFrame.setVisible(true);
snakeFrame.add(new JLabel(new ImageIcon("Images/Snake.png")));
snakeFrame.pack();

이 답변은 @shawalli의 답변을 보완하는 것입니다 ...

나는 항아리 안에 이미지를 참조하고 싶었지만 완충학을 갖는 대신 간단하게했다.

 JPanel jPanel = new JPanel();      
 jPanel.add(new JLabel(new ImageIcon(getClass().getClassLoader().getResource("resource/images/polygon.jpg"))));

자신의 사용을 피할 수 있습니다 ComponentS 및 SwingX 라이브러리 및 ImageIO 수업:

File f = new File("hello.jpg");
JLabel imgLabel = new JLabel(new ImageIcon(file.getName()));

나는 OP의 세 가지 질문을 실제로 다루지 않고 많은 답변을 볼 수 있습니다.

1) 성능에 관한 단어 : 디스플레이 어댑터와 일치하는 정확한 픽셀 바이트 순서를 사용할 수 없다면 바이트 어레이는 비효율적 일 수 있습니다.

최상의 도면 성능을 달성하려면 이미지를 현재 그래픽 구성에 해당하는 유형으로 생성 된 BufferedImage로 변환하십시오. createcompatibleimage를 참조하십시오 https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html

이 이미지는 프로그래밍 노력없이 몇 번 그리는 후 디스플레이 카드 메모리에 자동으로 캐시됩니다 (Java 6 이후 스윙의 표준). 따라서 실제 도면에는 무시할만한 시간이 소요됩니다. 만약에 이미지를 변경하지 않았습니다.

이미지를 변경하면 메인 메모리와 GPU 메모리 사이에 추가 메모리 전송이 제공됩니다. 이미지를 완충 시민으로 "다시 그리기"하지 않으므로 모든 수단에서 GetPixel과 SetPixel을 수행하지 마십시오.

예를 들어, 게임을 개발하는 경우 모든 게임 배우를 BufferedImage로 그리고 jpanel로 끌어들이는 대신 모든 액터를 더 작은 완충 지체로로드하고 JPANEL 코드로 하나씩 jpanel 코드로 그려 두는 것이 훨씬 빠릅니다. 그들의 적절한 위치 -이 방법으로 캐싱에 대한 이미지의 초기 전송을 제외하고 주 메모리와 GPU 메모리 사이에는 추가 데이터 전송이 없습니다.

ImageIcon은 후드 아래에서 BufferedImage를 사용하지만 기본적으로 BufferedImage를 적절한 그래픽 모드가 핵심이며,이를 제대로하려는 노력이 없습니다.

2) 이 작업을 수행하는 일반적인 방법은 JPANEL의 재정의 페인트 컴퓨터 방법에 완충학을 그리는 것입니다. Java는 GPU 메모리에 캐시 된 휘발성 휘발성 제어 버퍼 체인과 같은 많은 양의 추가 제품을 지원하지만 Java 6 이후로 GPU 가속도의 이러한 모든 세부 사항을 노출시키지 않으면 서 합리적으로 좋은 작업을 수행 할 필요가 없습니다.

GPU 가속도는 반투명 이미지 스트레칭과 같은 특정 작업에서는 작동하지 않을 수 있습니다.

3) 추가하지 마십시오. 위에서 언급 한대로 페인트하십시오.

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

이미지가 레이아웃의 일부인 경우 "추가"가 의미가 있습니다. JPANEL을 채우는 배경 또는 전경 이미지로 이것을 필요로하는 경우 PaintComponent를 그만 두십시오. 이미지를 보여줄 수있는 일반적인 스윙 구성 요소를 양조하는 것을 선호하는 경우 동일한 스토리입니다 (Jcomponent를 사용하고 PaintComponent 메소드를 재정의 할 수 있음) - 추가하십시오. 이것 GUI 구성 요소 레이아웃에.

4) 배열을 완충학으로 변환하는 방법

바이트 어레이를 PNG로 변환 한 다음로드하는 것은 매우 자원 집약적입니다. 더 좋은 방법은 기존 바이트 어레이를 BufferedImage로 변환하는 것입니다.

그에 대한: 루프에 사용하지 마십시오 복사 픽셀. 매우 느립니다. 대신에:

  • BufferedImage의 선호하는 바이트 구조를 배우십시오 (요즘 픽셀 당 4 바이트 인 RGB 또는 RGBA를 가정하는 것이 안전합니다)
  • 스캔 라인을 배우고 사용중인 스캔 (예 : 142 픽셀 너비의 이미지를 가질 수 있지만 실제 생활에서는 256 픽셀 폭 바이트 어레이로 저장 될 수 있습니다. )
  • 그런 다음 이러한 원리에 따라 배열 빌드가 있으면 BufferedImage의 SetRGB 배열 메소드가 배열을 BufferedImage에 복사 할 수 있습니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top