我已经找到了,并且非常适合我尝试过的一个gif。
我不知道他到底在做什么,但是乍一看, 如果第一帧的延迟为0,它将覆盖所有帧的延迟,即为10。然后他“写入”内存中的新GIF文件并将其加载到图片。
[编辑]我将它擦亮了一点,并消除了这些错误。
- 没有专有的API
- 不只是检查第一帧以确定它是否被窃听,
仅将延迟替换为零的帧。
public static Image readImgFromFile(String filename, Component parent) {
File file = new File(filename);
if (!file.exists()) {
return null;
}// Fix for bug when delay is 0try { // Load anything but GIF the normal way if (!filename.substring(filename.length() - 4).equalsIgnoreCase(".gif")) { return ImageIO.read(file); } // Get GIF reader ImageReader reader = ImageIO.getImageReadersByFormatName("gif").next(); // Give it the stream to depre from reader.setInput(ImageIO.createImageInputStream(file)); int numImages = reader.getNumImages(true); // Get 'metaFormatName'. Need first frame for that. IIOmetadata imagemetaData = reader.getImagemetadata(0); String metaFormatName = imagemetaData.getNativemetadataFormatName(); // Find out if GIF is bugged boolean foundBug = false; for (int i = 0; i < numImages && !foundBug; i++) { // Get metadata IIOmetadataNode root = (IIOmetadataNode)reader.getImagemetadata(i).getAsTree(metaFormatName); // Find GraphicControlExtension node int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { // Get delay value String delay = ((IIOmetadataNode)node).getAttribute("delayTime"); // Check if delay is bugged if (Integer.parseInt(delay) == 0) { foundBug = true; } break; } } } // Load non-bugged GIF the normal way Image image; if (!foundBug) { image = Toolkit.getDefaultToolkit().createImage(filename); } else { // Prepare streams for image encoding ByteArrayOutputStream baoStream = new ByteArrayOutputStream(); try (ImageOutputStream ios = ImageIO.createImageOutputStream(baoStream)) { // Get GIF writer that's compatible with reader ImageWriter writer = ImageIO.getImageWriter(reader); // Give it the stream to enpre to writer.setOutput(ios); writer.prepareWriteSequence(null); for (int i = 0; i < numImages; i++) { // Get input image BufferedImage frameIn = reader.read(i); // Get input metadata IIOmetadataNode root = (IIOmetadataNode)reader.getImagemetadata(i).getAsTree(metaFormatName); // Find GraphicControlExtension node int nNodes = root.getLength(); for (int j = 0; j < nNodes; j++) { Node node = root.item(j); if (node.getNodeName().equalsIgnoreCase("GraphicControlExtension")) { // Get delay value String delay = ((IIOmetadataNode)node).getAttribute("delayTime"); // Check if delay is bugged if (Integer.parseInt(delay) == 0) { // Overwrite with a valid delay value ((IIOmetadataNode)node).setAttribute("delayTime", "10"); } break; } } // Create output metadata IIOmetadata metadata = writer.getDefaultImagemetadata(new ImageTypeSpecifier(frameIn), null); // Copy metadata to output metadata metadata.setFromTree(metadata.getNativemetadataFormatName(), root); // Create output image IIOImage frameOut = new IIOImage(frameIn, null, metadata); // Enpre output image writer.writeToSequence(frameOut, writer.getDefaultWriteParam()); } writer.endWriteSequence(); } // Create image using enpred data image = Toolkit.getDefaultToolkit().createImage(baoStream.toByteArray()); } // Trigger lazy loading of image MediaTracker mt = new MediaTracker(parent); mt.addImage(image, 0); try { mt.waitForAll(); } catch (InterruptedException e) { image = null; } return image;}catch (IOException e) { e.printStackTrace(); return null;}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)