Java ImageWriter BufferedImage to GIF


Я надеюсь, что вы, ребята, сможете помочь мне с этим. Я не уверен, является ли это ошибкой в Java или я делаю что-то неправильно, но я пойду с последним.

Я хочу превратить Буферизованное изображение в GIF-изображение. Затем я хочу сохранить GIF в памяти в виде массива байтов. (Я не хочу сохранять файл на диск)

Программа должна захватить сегмент экрана (просто чтобы создать быстрое изображение) и превратить его в массив байтов GIF с помощью ImageIO ImageWriter и Bytearrayoutputstream не.

Приведенный ниже код покажет вам ошибку. Программа аварийно завершит работу и выдаст исключение ArrayIndexOutOfBoundsException, а массив останется пустым. Если вы замените "gif" на "png", он будет работать просто отлично, отсюда моя путаница. И еще! Если я сохраню образ в файл на диске с помощью

write.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File("C:/Image.gif")));

Он сохранит его в a .файл 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]);
    }
2 2

2 ответа:

Похоже, что в 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

Надеюсь, это поможет!