Преобразование BufferedImage в байт [] без ввода-вывода

Привет У меня есть экземпляр BufferedImage в памяти и вы хотите преобразовать его в байт [] для кодирования в качестве строки base64 без операции ввода-вывода для оценки производительности. Я использовал следующий API:

ByteArrayOutputStream baos = new ByteArrayOutputStream ();
ImageIO.write(image,"png",baos);
return baos.toByteArray();

Однако этот API все еще неявно записывает изображение в папку tem temp OS, что приведет к сбою в случае, если базовый каталог temp temp заполнен и временный файл не может быть создан. Трассировка стека:

Caused by: java.io.IOException: No space left on device
    at java.io.RandomAccessFile.write(RandomAccessFile.java:493)
    at javax.imageio.stream.FileCacheImageOutputStream.write(FileCacheImageOutputStream.java:134)
    at javax.imageio.stream.ImageOutputStreamImpl.write(ImageOutputStreamImpl.java:66)
    at com.sun.imageio.plugins.png.PNGImageWriter.write_magic(PNGImageWriter.java:376)
    at com.sun.imageio.plugins.png.PNGImageWriter.write(PNGImageWriter.java:1115)
    at javax.imageio.ImageWriter.write(ImageWriter.java:628)
    at javax.imageio.ImageIO.write(ImageIO.java:1480)
    at javax.imageio.ImageIO.write(ImageIO.java:1554)

Есть ли эффективный (например, преобразование в памяти или эффективный ввод-вывод) для преобразования без ввода-вывода? Просьба сообщить.

Ответ 1

Отключите кеш ImageIO с помощью метода ImageIO.setUseCache():

ImageIO.setUseCache(false);

Он включен по умолчанию в соответствии с javadoc:

Устанавливает флаг, указывающий, следует ли использовать файл кеша на диске при создании ImageInputStreams и ImageOutputStreams.

При чтении из стандартного InputStream > может потребоваться сохранить ранее прочитанную информацию в кеше, поскольку базовый поток не позволяет перечитывать данные. Аналогично, при записи на стандартный OutputStream кеш может использоваться, чтобы позволить ранее записанное значение быть изменено, прежде чем погрузить его в конечный пункт назначения.

Кэш может находиться в основной памяти или на диске. Установка этого флага в значение false запрещает использование диска для будущих потоков, что может быть выгодно при работе с небольшими изображениями, поскольку издержки на создание и уничтожение файлов удаляются.

При запуске значение равно true.

Ответ 2

ImageIO по умолчанию записывает кеш на диск, даже если вы используете только потоки. Попробуйте отключить кеш с помощью:

ImageIO.setUseCache(false);

Ответ 3

Оба упоминания ImageIO.setUseCache(false) верны. Однако, если вам не нравится отключать кэширование дисков для ImageIO глобально, альтернативой является явно перенос потока в MemoryCacheImageOutputStream (который делает кэширование в памяти вместо кэширования диска):

ByteArrayOutputStream baos = new ByteArrayOutputStream ();
ImageOutputStream stream = new MemoryCacheImageOutputStream(baos);
ImageIO.write(image, "png", stream);
stream.close();
return baos.toByteArray();

Ответ 4

((DataBufferByte)img.getRaster().getDataBuffer()).getData() автоматически возвращает массив байтов, если ваше изображение было в байтовом формате. Не требуется никакого ввода-вывода.