我希望你们能帮我解决这个问题。我不确定这是 Java 中的错误还是我做错了什么,但我会选择后者。
我想将缓冲图像转换为GIF图像。然后,我希望将 GIF 以字节数组的形式保存在内存中。(我不想将文件保存到磁盘)
程序应该捕获一个屏幕片段(只是为了创建一个快速图像),并使用ImageIO ImageWriter和ByteArrayOutputStream将其转换为GIF字节数组。
下面的代码将向您展示该错误。程序将崩溃并给出一个 ArrayIndexOutOfBoundsException,并且数组保持为空。如果您将"gif"替换为"png",它将正常工作,因此我感到困惑。也!如果我将图像保存到磁盘上的文件
write.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File("C:/Image.gif")));
它会将其正确保存到.gif文件中。
所以我的问题是,我在这一段代码中做错了什么?任何帮助将不胜感激!:)
注意:这不是动画GIF,也不涉及透明度。
String format = "gif";
Robot r = null;
try {
r = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
BufferedImage screen = r.createScreenCapture(new Rectangle(512,512));
final BufferedImage gif = new BufferedImage(512,512,BufferedImage.TYPE_BYTE_INDEXED);
Graphics2D g = gif.createGraphics();
g.drawImage(screen,0,0,null);
g.dispose();
ImageWriter write = ImageIO.getImageWritersBySuffix(format).next();
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
write.setOutput(ImageIO.createImageOutputStream(out));
write.write(gif);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for(int i=0; i < 10; i++) {
System.out.println(out.toByteArray()[i]);
}
com.sun.imageio.plugins.gif.*
中有一些奇怪的(如果不是明显的错误)流缓冲实现。如果不显式刷新或关闭 ImageOutputStream,则即使在关闭基础流后,也不会刷新内容。改变
write.setOutput(ImageIO.createImageOutputStream(out));
write.write(gif);
自
ImageOutputStream imageos = ImageIO.createImageOutputStream(out);
write.setOutput(imageos);
write.write(gif);
imageos.close(); // or imageos.flush();
使用ByteArrayOutputStream
来获取字节形式的图像。要写入此ByteArrayOutputStream
,您应该用ImageOutputStream
将其包装。
ImageWriter jpgWriter = ImageIO.getImageWritersByFormatName("gif").next();
//got imagewriter for gif
ImageWriteParam gifWriteParam = jpgWriter.getDefaultWriteParam();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageOutputStream ios=ImageIO.createImageOutputStream(baos);
jpgWriter.setOutput(ios);
jpgWriter.write(null,new IIOImage(myBufferedImageObject, null, null),gifWriteParam);
baos.flush();
byte[] buf= baos.toByteArray();//got as bytes here
希望这有帮助!