2012-01-13 11 views
0

アニメーションテクスチャをOpenGLゲームにシームレスに実装しようとしています。任意のBufferedImageをByteBufferに変換する汎用のImageDecoderクラスを作成しました。それは今のところ完璧に動作しますが、アニメーション画像は読み込まれません。アニメーション画像をBufferedImage配列にロードする

私はImageIconとしてアニメーション画像をロードしようとしていません。 OpenGL準拠のByteBufferを取得するには、BufferedImageが必要です。

アニメーションイメージ内のすべてのフレームをBufferedImage配列としてロードするにはどうすればよいですか? 同様の注記で、アニメーションレート/期間を取得するにはどうすればよいですか?

JavaはAPNGを処理しますか?

答えて

0

私は、JavaがデフォルトでAPNGをサポートしていないと思いますが、あなたはそれを解析するためにサードパーティのライブラリを使用することができます:あなたの最も簡単な方法かもしれません

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

を。あなたがたImageObserverを登録する必要がアニメーションGIFのフレームを取得するためとして:)

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(ので、これは別のスレッドで非同期的にロードし、すぐに呼ばれることはありません。しかし、それはそれを解析するごとにフレームごとに呼び出されます。

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

+0

私はライブラリを使用しました。私はアニメーションPNGをサポートするために自分のjarファイルを作成しなければなりませんでしたが、今はすべてが意図したとおりに動作します。 – 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; 
} 
関連する問題