2

Java スクリーン ショットのアニメーションについて質問があります。私のアプリケーションは、robot()関数とループを使用して複数のスクリーンショットを撮り、名前を付けて、1 からループ番号まで連続した順序で保存しています。

問題は、それらの画像を「ムービー」に入れる必要があるということですが、形式はそれほど重要ではありません。残念ながら、これを行う方法がわからず、旅行中にiPadを使用しています。

編集: 私が言いたいのは、Java アプリケーションからこれらのスクリーンショットを使ってムービーやアニメーションを作成できるものが必要だということです。

4

3 に答える 3

4

次のように、サードパーティのライブラリを使用せずにアニメーション GIF を作成できます。

void writeAnimatedGif(OutputStream stream,
                      Iterable<BufferedImage> frames,
                      int delayInMilliseconds,
                      Integer repeatCount)
throws IOException {
    try (ImageOutputStream iioStream =
            ImageIO.createImageOutputStream(stream)) {

        ImageWriter writer =
            ImageIO.getImageWritersByMIMEType("image/gif").next();
        writer.setOutput(iioStream);

        writer.prepareWriteSequence(null);

        for (BufferedImage frame : frames) {
            writeFrame(frame, delayInMilliseconds, writer, repeatCount);
            repeatCount = null;
        }

        writer.endWriteSequence();
        writer.dispose();
    }
}

void writeFrame(BufferedImage image,
                int delayInMilliseconds,
                ImageWriter writer,
                Integer repeatCount)
throws IOException {
    ImageTypeSpecifier type =
        ImageTypeSpecifier.createFromRenderedImage(image);
    IIOMetadata metadata = writer.getDefaultImageMetadata(type, null);
    String format = metadata.getNativeMetadataFormatName();

    Node tree = metadata.getAsTree(format);

    if (repeatCount != null)
    {
        setRepeatCount(repeatCount, tree);
    }

    setDelayTime(delayInMilliseconds, tree);

    metadata.setFromTree(format, tree);

    writer.writeToSequence(new IIOImage(image, null, metadata), null);
}

private void setRepeatCount(Number repeatCount, Node imageMetadata)
{
    Element root = (Element) imageMetadata;

    ByteBuffer buf = ByteBuffer.allocate(3).order(ByteOrder.LITTLE_ENDIAN);
    buf.put((byte) 1);  // sub-block index (always 1)
    byte[] appExtBytes = buf.putShort(repeatCount.shortValue()).array();

    Element appExtContainer;
    NodeList nodes = root.getElementsByTagName("ApplicationExtensions");
    if (nodes.getLength() > 0) {
        appExtContainer = (Element) nodes.item(0);
    } else {
        appExtContainer = new IIOMetadataNode("ApplicationExtensions");

        Node reference = null;
        nodes = root.getElementsByTagName("CommentExtensions");
        if (nodes.getLength() > 0) {
            reference = nodes.item(0);
        }

        root.insertBefore(appExtContainer, reference);
    }

    IIOMetadataNode appExt =
        new IIOMetadataNode("ApplicationExtension");
    appExt.setAttribute("applicationID", "NETSCAPE");
    appExt.setAttribute("authenticationCode", "2.0");
    appExt.setUserObject(appExtBytes);

    appExtContainer.appendChild(appExt);
}


private void setDelayTime(int delayInMilliseconds, Node imageMetadata)
{
    Element root = (Element) imageMetadata;

    Element gce;
    NodeList nodes = root.getElementsByTagName("GraphicControlExtension");
    if (nodes.getLength() > 0) {
        gce = (Element) nodes.item(0);
    } else {
        gce = new IIOMetadataNode("GraphicControlExtension");

        Node reference = null;
        nodes = root.getElementsByTagName("PlainTextExtension");
        if (nodes.getLength() > 0) {
            reference = nodes.item(0);
        }
        if (reference == null) {
            nodes = root.getElementsByTagName("ApplicationExtensions");
            if (nodes.getLength() > 0) {
                reference = nodes.item(0);
            }
        }
        if (reference == null) {
            nodes = root.getElementsByTagName("CommentExtensions");
            if (nodes.getLength() > 0) {
                reference = nodes.item(0);
            }
        }

        root.insertBefore(gce, reference);
    }

    gce.setAttribute("delayTime",
        String.valueOf(delayInMilliseconds / 10));
}

http://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/gif_metadata.html#gif_image_metadata_formatも参照してください。

于 2013-10-28T15:31:53.523 に答える
1

(廃止され、放棄された) Java Media Framework は、JPEG を MOV に変換できます。ただし、(実装されている特定の圧縮コーデックを使用して) 非常に圧縮率が高く、ファイル サイズが巨大になることに注意してください。この回答で例を見ることができます。

于 2013-10-28T13:22:22.723 に答える