问题
- What is the fastest way to read Images from a File into a BufferedImage in Java/Grails?
- What is the fastest way to write Images from a BufferedImage into a File in 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()
回答1:
Your solution to read is basically reading the bytes twice, once from the file and once from the ByteArrayInputStream
. Don't do that
With Java 7 to read
BufferedImage bufferedImage = ImageIO.read(Files.newInputStream(Paths.get(basePath + imageSource)));
With Java 7 to write
ImageIO.write(bufferedImage, "jpg", Files.newOutputStream(Paths.get(fullPath)));
The call to Files.newInputStream
will return a ChannelInputStream
which (AFAIK) is not buffered. 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.
回答2:
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. 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).
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. This is obviously not a good idea if you are dealing with very large images.
回答3:
You are almost good for writing. Just don't use the intermediate ByteArrayOutputStream. It is a giant bottleneck in your code. Instead wrap the FileOutputStream in a BufferedOutputStream and do the same.
Same goes indeed for your reading. Remove the Itermediate ByteArrayInputStream.
来源:https://stackoverflow.com/questions/18522398/fastest-way-to-read-write-images-from-a-file-into-a-bufferedimage