Самый быстрый способ чтения / записи изображений из файла в BufferedImage?
- каков самый быстрый способ чтения изображений из файла в BufferedImage в Java / Grails?
- каков самый быстрый способ записи изображений из BufferedImage в файл в Java/Grails?
мой вариант (чтение):
byte [] imageByteArray = new File(basePath+imageSource).readBytes()
InputStream inStream = new ByteArrayInputStream(imageByteArray)
BufferedImage bufferedImage = ImageIO.read(inStream)
мой вариант (напишите):
BufferedImage bufferedImage = // some image
def fullPath = // image page + file name
byte [] currentImage
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write( bufferedImage, "jpg", baos );
baos.flush();
currentImage = baos.toByteArray();
baos.close();
}catch(IOException e){
System.out.println(e.getMessage());
}
}
def newFile = new FileOutputStream(fullPath)
newFile.write(currentImage)
newFile.close()
3 ответов
ваше решение для чтения в основном читает байты дважды, один раз из файла и один раз из ByteArrayInputStream
. Не делай этого!--7-->
С Java 7 для чтения
BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get(basePath + imageSource)));
С Java 7 для записи
ImageIO.write(bufferedImage, "jpg", Files.newOutputStream(Paths.get(fullPath)));
вызов Files.newInputStream
вернет ChannelInputStream
который (AFAIK) не буферизован. Вы захотите завернуть его
new BufferedInputStream(Files.newInputStream(...));
чтобы было меньше вызовов ввода-вывода на диск, в зависимости от того, как вы его используете.
Я опаздываю на вечеринку, но в любом случае...
на самом деле, использовать:
ImageIO.read(new File(basePath + imageSource));
и
ImageIO.write(bufferedImage, "jpeg", new File(fullPath));
...может оказаться быстрее (попробуйте, используя профилировщик, чтобы убедиться).
это потому, что эти варианты используют RandomAccessFile
- backed ImageInputStream
/ImageOutputStream
реализаций за кулисами, в то время как InputStream
/OutputStream
- версии по умолчанию будут использовать реализацию потока поиска с поддержкой диска. Резервное копирование диска включает запись всего содержимого поток во временный файл и, возможно, чтение из него (это связано с тем, что ввод-вывод изображений часто выигрывает от нелинейного доступа к данным).
если вы хотите избежать дополнительного ввода-вывода с потоковыми версиями, за счет использования большего объема памяти, можно вызвать двусмысленно названный ImageIO.setUseCache(false)
, чтобы отключить кэширование диска искомых входных потоков. Это, очевидно, не очень хорошая идея, если вы имеете дело с очень большими изображениями.
вы почти хороши для письма. Просто не используйте промежуточный ByteArrayOutputStream. Это гигантское узкое место в вашем коде. Вместо этого оберните FileOutputStream в BufferedOutputStream и сделайте то же самое.
то же самое касается вашего чтения. Удалите Itermediate ByteArrayInputStream.