2
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import common.ResourcesToAccess;

public class RecordingStartingThread extends Thread{
    @Override
    public void run(){
        JFrame f = new JFrame();
        ImageIcon reel = new ImageIcon("src/images/reel.GIF");
        JLabel label = new JLabel(reel);
        reel.setImageObserver(label);
        f.getContentPane().add(label);
        f.setUndecorated(true);
        f.setSize(300, 300);
        f.setVisible(true);
    }
    public static void main(String[] args) {
        new RecordingStartingThread().start();
    } 
}

問題: GIFは非常に高速に再生されます。

質問: GIFが通常の速度で再生されることを確認するにはどうすればよいですか?

4

2 に答える 2

3

GIF速度の再生に関しては-私もこの問題に遭遇しました。私が正しく覚えている場合、これはGIFファイルのフレームレートの「デフォルト」(または提供されていない?)値が原因でした。一部のWebブラウザは、GIFが正しく再生されるように、そのフレームレートを「オーバーライド」しました。

その結果、GIFを変換し(GIFを読み取る-> GIFを書き込む)、ユーザーが提供するフレームレートを提供するクラスを作成しました。com.madgag.gif.fmsware.AnimatedGifEncoderclassは、Mavenを介してプロジェクトにリンクする外部ライブラリです。animated-gif-lib-1.0.jar

public final class GIFUtils {

private GIFUtils() {
}

public static List<BufferedImage> extractFrames(String filePath) throws IOException {
    return extractFrames(new File(filePath));
}

public static List<BufferedImage> extractFrames(File file) throws IOException {
    List<BufferedImage> imgs = new LinkedList<BufferedImage>();
    ImageReader reader = ImageIO.getImageReadersBySuffix("GIF").next();
    ImageInputStream in = null;
    try {
        in = ImageIO.createImageInputStream(new FileInputStream(file));
        reader.setInput(in);
        BufferedImage img = null;
        int count = reader.getNumImages(true);
        for(int i = 0; i < count; i++) {
            Node tree = reader.getImageMetadata(i).getAsTree("javax_imageio_gif_image_1.0");
            int x = Integer.valueOf(tree.getChildNodes().item(0).getAttributes()
                    .getNamedItem("imageLeftPosition").getNodeValue());
            int y = Integer.valueOf(tree.getChildNodes().item(0).getAttributes()
                    .getNamedItem("imageTopPosition").getNodeValue());
            BufferedImage image = reader.read(i);
            if(img == null) {
                img = new BufferedImage(image.getWidth() + x, image.getHeight() + y,
                        BufferedImage.TYPE_4BYTE_ABGR);
            }

            Graphics2D g = img.createGraphics();
            ImageUtils.setBestRenderHints(g);
            g.drawImage(image, x, y, null);
            imgs.add(ImageUtils.copy(img));
        }
    }
    finally {
        if(in != null) {
            in.close();
        }
    }
    return imgs;
}

public static void writeGif(List<BufferedImage> images, File gifFile, int millisForFrame)
        throws FileNotFoundException, IOException {
    BufferedImage firstImage = images.get(0);
    int type = firstImage.getType();

    ImageOutputStream output = new FileImageOutputStream(gifFile);

    // create a gif sequence with the type of the first image, 1 second
    // between frames, which loops continuously
    GifSequenceWriter writer = new GifSequenceWriter(output, type, 100, false);

    // write out the first image to our sequence...
    writer.writeToSequence(firstImage);
    for(int i = 1; i < images.size(); i++) {
        BufferedImage nextImage = images.get(i);
        writer.writeToSequence(nextImage);
    }

    writer.close();
    output.close();
}

public static Image createGif(List<BufferedImage> images, int millisForFrame) {
    AnimatedGifEncoder g = new AnimatedGifEncoder();
    ByteArrayOutputStream out = new ByteArrayOutputStream(5 * 1024 * 1024);
    g.start(out);
    g.setDelay(millisForFrame);
    g.setRepeat(1);
    for(BufferedImage i : images) {
        g.addFrame(i);
    }
    g.finish();
    byte[] bytes = out.toByteArray();
    return Toolkit.getDefaultToolkit().createImage(bytes);
}

そしてGifSequenceWriterこのように見えます:

public class GifSequenceWriter {
    protected ImageWriter gifWriter;
    protected ImageWriteParam imageWriteParam;
    protected IIOMetadata imageMetaData;

    public GifSequenceWriter(ImageOutputStream outputStream, int imageType, int timeBetweenFramesMS,
            boolean loopContinuously) throws IIOException, IOException {
        gifWriter = getWriter();
        imageWriteParam = gifWriter.getDefaultWriteParam();
        ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(imageType);

        imageMetaData = gifWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);

        String metaFormatName = imageMetaData.getNativeMetadataFormatName();

        IIOMetadataNode root = (IIOMetadataNode) imageMetaData.getAsTree(metaFormatName);

        IIOMetadataNode graphicsControlExtensionNode = getNode(root, "GraphicControlExtension");

        graphicsControlExtensionNode.setAttribute("disposalMethod", "none");
        graphicsControlExtensionNode.setAttribute("userInputFlag", "FALSE");
        graphicsControlExtensionNode.setAttribute("transparentColorFlag", "FALSE");
        graphicsControlExtensionNode.setAttribute("delayTime", Integer.toString(timeBetweenFramesMS / 10));
        graphicsControlExtensionNode.setAttribute("transparentColorIndex", "0");

        IIOMetadataNode commentsNode = getNode(root, "CommentExtensions");
        commentsNode.setAttribute("CommentExtension", "Created by MAH");

        IIOMetadataNode appEntensionsNode = getNode(root, "ApplicationExtensions");

        IIOMetadataNode child = new IIOMetadataNode("ApplicationExtension");

        child.setAttribute("applicationID", "NETSCAPE");
        child.setAttribute("authenticationCode", "2.0");

        int loop = loopContinuously ? 0 : 1;

        child.setUserObject(new byte[] { 0x1, (byte) (loop & 0xFF), (byte) (loop >> 8 & 0xFF) });
        appEntensionsNode.appendChild(child);

        imageMetaData.setFromTree(metaFormatName, root);

        gifWriter.setOutput(outputStream);

        gifWriter.prepareWriteSequence(null);
    }

    public void writeToSequence(RenderedImage img) throws IOException {
        gifWriter.writeToSequence(new IIOImage(img, null, imageMetaData), imageWriteParam);
    }

    public void close() throws IOException {
        gifWriter.endWriteSequence();
    }

    private static ImageWriter getWriter() throws IIOException {
        Iterator<ImageWriter> iter = ImageIO.getImageWritersBySuffix("gif");
        if(!iter.hasNext()) {
            throw new IIOException("No GIF Image Writers Exist");
        }
        return iter.next();
    }

    private static IIOMetadataNode getNode(IIOMetadataNode rootNode, String nodeName) {
        int nNodes = rootNode.getLength();
        for(int i = 0; i < nNodes; i++) {
            if(rootNode.item(i).getNodeName().compareToIgnoreCase(nodeName) == 0) {
                return (IIOMetadataNode) rootNode.item(i);
            }
        }
        IIOMetadataNode node = new IIOMetadataNode(nodeName);
        rootNode.appendChild(node);
        return node;
    }
}
于 2012-12-27T15:37:29.833 に答える
0

この問題の最も簡単な解決策は、「整形式」、つまり適切なフレームレートを含む.gifファイルを作成することです。これは、グーグルの「gifスピードチェンジャー」だけで、さまざまなオンラインコンバーターの助けを借りて達成することができます。

于 2014-06-02T08:46:55.783 に答える