2010-12-06 1 views
5

한 이미지의 일부를 다른 작은 이미지로 복사하고 싶습니다. 즉, 하위 직사각형을 복사하십시오. 한 이미지의 일부를 다른 이미지로 복사하려면 어떻게합니까?

는 내가 대상 하나를 만들 수 있습니다, 소스에 대한 의 Graphics2D 객체를 가지고 있고, 나는 약 targetGraphics2D.drawImage 알고 (이미지 IMG을, ....)을하지만, 어떻게하는 것이합니까 IMG sourceGraphics2D? (aioobe 당)


답변 : 소스는 이미지보다는 의 Graphics2D 할 필요가있다.

Image.subImage()은 소스의 관련 부분을 가져 오는 방법입니다.

+2

이 서브 이미지는() 기본 복사하지 않는다는 것을 알고 있어야합니다 적어도 BufferedImage로 이미지 데이터 따라서 subImage()에서 얻은 Image를 그리면 원본을 수정하고 target.createGraphics(). drawImage (Image img, ...)를 사용하면 실제로 사본을 만듭니다. – Trilarion

답변

0

첫째, 일부 Andreas_D 아래 답변에 대한 참고 사항 :

  • 그의 코드는 내부 및 문서화되지 않은 오픈 JDK 클래스입니다 sun.java2d.SunGraphics2D에 의존합니다. 즉, 컴퓨터에서 컴파일 및 실행될 수 있지만 일 수 있습니다. 은 코드를 다른 사람에게 배포 할 경우 문제가 발생할 수 있습니다. 자세한 내용은 official statement을 참조하십시오.

  • 코드는 자체에서 코드 냄새가 나는 내부 클래스 열기를 들으려면 리플렉션에 의존합니다. 모두

  • 모두는 그의 접근 방식은 매우 나쁜 관행의 예입니다 (모두는 프로그래밍 스타일에 올 때 올바르게 API를 사용하는 동료 프로그래머를 돕는 때)


sourceGraphics2D에서 해당 img를 얻으려면 어떻게해야하나요?

귀하는 Graphics2D 클래스의 책임을 잘못 이해 한 것으로 의심됩니다.

Graphics2D 클래스를 사용하여 무언가를 그립니다. BufferedImage (버퍼링 된 이미지에서 그래픽 개체가있는 경우), 화면 (paintComponent 메서드의 인수로 가져온 경우) 또는 프린터에서 그리기가 가능합니다. 즉, Graphics2D 개체가 주어지면 이미지가 존재하지 않을 수도 있습니다.

아마도 이해할 수 있듯이 Graphics2D API는 기본 이미지를 가져 오는 방법을 제공하지 않습니다. (이러한 방법은 의미가 없으므로 그래픽 객체가 선과 텍스트를 프린터로 전달할 수 있습니다!)

하위 이미지를 얻으려면 주어진 그래픽 객체가있는 기본 이미지를 확보해야합니다 그립니다.

+0

OK, 이해합니다. 소스는 Graphics2D가 아닌 Image 여야합니다. 그런 다음 Image.subImage()는 클립을 가져 오는 메서드입니다. –

+0

예. 뭔가 그런 :-) – aioobe

+2

아하, 항상 방법이 있습니다! (그리고이 경우에 : "연필"은 그려진 것을 기억합니다 ;-)) –

3

Aioobe가 말했듯이, 당신은 Graphics2D만으로 이미지를 얻지 못할 것입니다.그러나 sourceGraphics2D가 Swing 구성 요소에서 나온 것이라면 자신의 Graphics2D 인스턴스로 페인트 메서드를 호출 해보십시오. 거기에서 흥미있는 하위 영역을 복사 할 수 있습니다.

이것은 일종의 해킹이나 스윙 개체를 사용한다고 가정하면 작동합니다.

class CopySwingPaintingSubRegion extends TheSourceType 
{ 
     private BufferedImage bufImg; 

     public CopySwingPaintingSubRegion() 
     { 
      bufImg = new BufferedImage(...); 

      //Draw the original image into our bufImg for copying 
      super.paintComponent(bufImg.createGraphics()); 
     } 

     public BufferedImage getSubImage(int x, int y, int w, int h) 
     { 
      return bufImg.getSubImage(x,y,w,h); 
     } 
} 
3

짧은 답변 : 예, 당신은 버퍼 이미지 에 생성 된

Graphics2D 객체는 이미지를 알고 있지만, 그것을 다시 손을 기꺼이하지 않습니다 수 있습니다. 리플렉션 사용에 신경 쓰지 않는다면 도둑질 (반사) 할 수 있습니다. 다음 코드는 접근 방식을 보여줍니다.

public class Graphics2DReflector { 

    public static void main(String[] args) { 
    // prepare the Graphics2D - note, we don't keep a ref to the image! 
    final Graphics2D g2d = 
      new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB).createGraphics(); 
    g2d.drawString("Reflected", 10, 50); 


    JFrame frame = new JFrame("Reflected Image"); 
    // one Panel to show the image only known by g2d 
    frame.getContentPane().add(new Panel() { 
     @Overwrite 
     public void paint(Graphics g) { 
     try { 
      SurfaceData data = ((SunGraphics2D) g2d).surfaceData; 
      Field bufImg = BufImgSurfaceData.class.getDeclaredField("bufImg"); 
      bufImg.setAccessible(true); 
      BufferedImage image = (BufferedImage) bufImg.get(data); 
      g.drawImage(image,0,0,null); 
     } catch (Exception oops) { 
      oops.printStackTrace(); 
     } 
     } 
    }); 
    frame.setSize(200,200); 
    frame.setVisible(); 
    } 
} 

참고 : 일부 Sun/Oracle 클래스에 따라 다르며 모든 Java VM에서 작동하지 않을 수 있습니다. 최소한 접근 방식을 보여 주므로 필드를 가져 오기 위해 실제 클래스를 검사해야 할 수도 있습니다.

+1

'sun. *'패키지와 반향을 같은 대답으로 사용합니다 .. hehe;) 적어도 상황을 나열해야합니다. 'Graphics2D' 오브젝트는 실제로'*''SunGraphics2D'입니까? [개발자가 프로그램을 작성하지 않아야하는 이유] 전화 'sun'패키지 (http://java.sun.com/products/jdk/faq/faq-sun-packages.html). – aioobe

+1

@aiobe - 안녕하세요, 해킹입니다. 이미 이러한 제한 사항에 대한 일반적인 메모를 추가했습니다. 당신은 ist가 작동하지 않는다고 말했다. 그리고 나는 방금 대답했다 : 그것은 가능하다. 전혀 휴대 할 수는 없지만 불가능한 것은 아닙니다. –

1

제대로 이해하면 W3Schools에는 이미지의 일부를 캔버스에 넣을 코드가 있습니다. 다른 이미지로 필요하다면 캔버스에서 가져올 수 있습니다.

나는 10 "세포 또는 프레임"가 200 폭 20 높이 하나 개의 PNG 이미지가 - 나는 애니메이션에 사용하고 아래의 방법을 사용하십시오

context.drawImage(img, sx, sy, swidth, sheight, x, y, width, height);