2012-01-13 3 views
0

애니메이션 텍스처를 OpenGL 게임에 완벽하게 구현하려고합니다. 나는 어떤 BufferedImage를 ByteBuffer로 번역하기 위해 일반적인 ImageDecoder 클래스를 만들었습니다. 애니메이션 이미지를로드하지는 않지만 완벽하게 작동합니다.BufferedImage 배열에 애니메이션 이미지로드

나는 애니메이션 이미지를 ImageIcon으로로드하려고하고 있지 않습니다. OpenGL 호환 ByteBuffer를 얻으려면 BufferedImage가 필요합니다.

어떻게 움직이는 이미지에서 모든 프레임을 BufferedImage 배열로로드 할 수 있습니까? 유사한 메모에서 애니메이션 속도/마침표는 어떻게 얻을 수 있습니까?

Java가 APNG를 처리합니까?

답변

0

나는 자바는 기본적으로 APNG를 지원합니다 생각하지 않습니다,하지만 당신은 그것을 분석하기 위해 제 3 자 라이브러리를 사용할 수 있습니다 : 당신의 가장 쉬운 방법이 될 수

http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300

합니다.

new ImageIcon(url).setImageObserver(new ImageObserver() { 
    public void imageUpdate(Image img, int infoFlags, int x, int y, int width, int height) { 
     if(infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS) { 
      // another frame was loaded do something with it. 
     } 
    } 
}); 

이 부하 비동기 이어 imageUpdate 그래서 다른 스레드()에 즉시 호출되지 않습니다 : 애니메이션 GIF에서 프레임을 얻기에 관해서 당신은의 ImageObserver를 등록해야합니다. 그러나 파싱 할 때마다 프레임마다 호출됩니다.

http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html

+0

나는 라이브러리를 사용했다. 애니메이션 PNG를 지원하기 위해 내 항아리를 만들어야했지만 이제 모든 것이 의도 한대로 작동합니다. – Klems

0

다음 코드는 "배열"부분을 수용하기 위해 내 자신의 구현에서 적응이다.

gif의 문제점은 다음과 같습니다. 모든 처리 방법을 고려해야 할 필요가 있습니다. 아래 코드는이를 보완하려고 시도합니다. 예를 들어, "doNotDispose"모드의 특별한 구현은, 모든 프레임을 선두로부터 N까지 취해, 그것들을 서로 위에 겹쳐 BufferedImage에 페인트합니다.

chubbsondubs가 게시 한 것보다이 방법의 장점은 gif 애니메이션 지연을 기다릴 필요가 없지만 기본적으로 즉시 수행 할 수 있다는 것입니다.

BufferedImage[] array = null; 
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream 
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream); 
while (imageReaders.hasNext()) 
{ 
    ImageReader reader = (ImageReader) imageReaders.next(); 
    try 
    { 
     reader.setInput(imageInputStream); 
     frames = reader.getNumImages(true); 
     array = new BufferedImage[frames]; 
     for (int frameId : frames) 
     { 
      int w = reader.getWidth(0); 
      int h = reader.getHeight(0); 
      int fw = reader.getWidth(frameId); 
      int fh = reader.getHeight(frameId); 
      if (h != fh || w != fw) 
      { 
       GifMeta gm = getGifMeta(reader.getImageMetadata(frameId)); 
       // disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious", 
       if ("doNotDispose".equals(gm.disposalMethod)) 
       { 
        image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 
        Graphics2D g = (Graphics2D) image.getGraphics(); 
        for (int f = 0; f <= frameId; f++) 
        { 
         gm = getGifMeta(reader.getImageMetadata(f)); 

         if ("doNotDispose".equals(gm.disposalMethod)) 
         { 
          g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition); 
         } 
         else 
         { 
          // XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod); 
         } 
        } 
        g.dispose(); 
       } 
       else 
       { 
        image = reader.read(frameId); 
        // XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod; 
       } 
      } 
      else 
      { 
       image = reader.read(frameId); 
      } 
      if (image == null) 
      { 
       throw new NullPointerException(); 
      } 
      array[frame] = image; 
     } 
    } 
    finally 
    { 
     reader.dispose(); 
    } 
} 
return array; 

private final static class GifMeta 
{ 

    String disposalMethod = "none"; 
    int imageLeftPosition = 0; 
    int imageTopPosition = 0; 
    int delayTime = 0; 
} 

private GifMeta getGifMeta(IIOMetadata meta) 
{ 
    GifMeta gm = new GifMeta(); 
    final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0"); 
    NodeList childNodes = gifMeta.getChildNodes(); 
    for (int i = 0; i < childNodes.getLength(); ++i) 
    { 
     IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i); 
     if (subnode.getNodeName().equals("GraphicControlExtension")) 
     { 
      gm.disposalMethod = subnode.getAttribute("disposalMethod"); 
      gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime")); 
     } 
     else if (subnode.getNodeName().equals("ImageDescriptor")) 
     { 
      gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition")); 
      gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition")); 
     } 
    } 
    return gm; 
}