Pergunta

I have a question about animating java screen shots. My application is using the robot() function and a loop to take multiple screenshots and save them with names in consecutive orders, 1 to the loop number.

The thing is I need to put those images into a "movie", the format doesn't matter all that much though. Unfortunately I have no clue how to do this and I'm on my iPad as I'm traveling.

EDIT: What I mean is I need something that can create a movie or animation from my Java application with those screenshots.

Foi útil?

Solução

You can create an animated GIF without a third-party library like this:

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));
}

See also http://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/doc-files/gif_metadata.html#gif_image_metadata_format .

Outras dicas

The (obsolete, abandoned) Java Media Framework can turn JPEGs into a MOV. Though note they have atrocious compression (using the particular compression codec implemented), and result in huge file sizes. An example can be seen in this answer.

You could use any GIF creator out there to generate a Movie from Pictures. Do you need to do this on your ipad? maybe use this app

Or use a website like this

But what exactly does this have to do with Java?

EDIT: as posted in the comment, a Java Class to creata a GIF from images is given in this post

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top