简体   繁体   English

从文件读取/写入图像到BufferedImage的最快方法?

[英]Fastest way to read/write Images from a File into a BufferedImage?

  1. What is the fastest way to read Images from a File into a BufferedImage in Java/Grails? 在Java / Grails中将图像从文件读取到BufferedImage的最快方法是什么?
  2. What is the fastest way to write Images from a BufferedImage into a File in Java/Grails? 将图像从BufferedImage写入Java / Grails文件的最快方法是什么?

my variant (read): 我的变种(读):

byte [] imageByteArray = new File(basePath+imageSource).readBytes()
InputStream inStream = new ByteArrayInputStream(imageByteArray)
BufferedImage bufferedImage = ImageIO.read(inStream)

my variant (write): 我的变种(写):

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()

Your solution to read is basically reading the bytes twice, once from the file and once from the ByteArrayInputStream . 您的读取解决方案基本上是两次读取字节,一次是从文件读取,一次是从ByteArrayInputStream读取。 Don't do that 不要那样做

With Java 7 to read 用Java 7来阅读

BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get(basePath + imageSource)));

With Java 7 to write 用Java 7来编写

ImageIO.write(bufferedImage, "jpg", Files.newOutputStream(Paths.get(fullPath)));

The call to Files.newInputStream will return a ChannelInputStream which (AFAIK) is not buffered. Files.newInputStream的调用将返回一个ChannelInputStream ,它不缓冲(AFAIK)。 You'll want to wrap it 你想要包装它

new BufferedInputStream(Files.newInputStream(...));

So that there are less IO calls to disk, depending on how you use it. 因此,对磁盘的IO调用较少,具体取决于您使用它的方式。

I'm late to the party, but anyway... 我迟到了,但无论如何......

Actually, using: 实际上,使用:

ImageIO.read(new File(basePath + imageSource));

and

ImageIO.write(bufferedImage, "jpeg", new File(fullPath));

...might prove faster (try it, using a profiler, to make sure). ...可能会更快(尝试使用分析器确保)。

This is because these variants use RandomAccessFile -backed ImageInputStream / ImageOutputStream implementations behind the scenes, while the InputStream / OutputStream -based versions will by default use a disk-backed seekable stream implementation. 这是因为这些变体在幕后使用RandomAccessFile -backed ImageInputStream / ImageOutputStream实现,而基于InputStream / OutputStream的版本将默认使用磁盘支持的可搜索流实现。 The disk-backing involves writing the entire contents of the stream to a temporary file and possibly reading back from it (this is because image I/O often benefits from non-linear data access). 磁盘备份涉及将流的全部内容写入临时文件并可能从中读回(这是因为图像I / O通常受益于非线性数据访问)。

If you want to avoid extra I/O with the stream based versions, at the cost of using more memory, it is possible to call the ambiguously named ImageIO.setUseCache(false) , to disable disk caching of the seekable input streams. 如果要避免使用基于流的版本的额外I / O,以使用更多内存为代价,可以调用名称不明确的ImageIO.setUseCache(false)来禁用可搜索输入流的磁盘缓存 This is obviously not a good idea if you are dealing with very large images. 如果你正在处理非常大的图像,这显然不是一个好主意。

You are almost good for writing. 你写作几乎不错。 Just don't use the intermediate ByteArrayOutputStream. 只是不要使用中间ByteArrayOutputStream。 It is a giant bottleneck in your code. 这是代码中的一个巨大瓶颈。 Instead wrap the FileOutputStream in a BufferedOutputStream and do the same. 而是将FileOutputStream包装在BufferedOutputStream中并执行相同操作。

Same goes indeed for your reading. 你的阅读也是如此。 Remove the Itermediate ByteArrayInputStream. 删除Itermediate ByteArrayInputStream。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM