问题描述
我正在使用 javax.imageio.ImageIO.read()
几乎需要 9 秒才能读取大小为 5 mb 且位于 windows 临时位置的图像,PFB Jprofiler 的屏幕截图.我想要一种更有效的方法,可以将时间减少到至少 2-3 秒.
I am using javax.imageio.ImageIO.read()
which almost takes 9 seconds to read an image having size 5 mb and located at windows temp location, PFB the screenshot of Jprofiler. i want a more efficient way which can decrease the time to at least 2-3 seconds.
该文件作为 org.springframework.web.multipart.MultipartFile 请求通过 rest 端点发出,然后被复制到 windows 临时位置以供进一步处理.完整的代码块:
The file is coming as a org.springframework.web.multipart.MultipartFile request through rest endpoint and then getting copied to the windows temp location for further proccessing. The complete code block:
String fileName = StringUtils.cleanPath(multipartFile.getOriginalFilename());
Path destinationPath = Paths.get(System.getProperty("java.io.tmpdir"));
String tempPath = destinationPath.resolve(fileName).toString();
File uploadedImageFile = new File(tempPath);
File originalFileInTempLocation = file.transferTo(uploadedImageFile);
BufferedImage originalImage = ImageIO.read(originalFileInTempLocation);
在谷歌搜索时,我发现了一个声称比 javax.imageio.ImageIO
效率更高的第三方库,但它是付费的:https://files.idrsolutions.com/maven/site/jdeli/apidocs/com/idrsolutions/image/JDeli.html#read(java.io.File).
While googling i found a 3rd party library which claims to be more efficient than javax.imageio.ImageIO
but its a paid one: https://files.idrsolutions.com/maven/site/jdeli/apidocs/com/idrsolutions/image/JDeli.html#read(java.io.File).
谁能建议一种更好更有效的方法来读取图像文件.
Can anyone suggest a better and efficient way to read the image file.
推荐答案
你的 9 秒时间看起来很糟糕 - 我想知道你是否包含了 ImageIO.read(File)
?
Your time of 9 seconds looks bad - I wonder if you've included all code and timing of just ImageIO.read(File)
?
但是我发现 ImageIO.read(File)
在非 SSD 驱动器上很慢(即 500 毫秒到 1 秒).在我的 PC 上测试 NAS 和 HDD 驱动器时,调用 InputStream.read() 的 4-6MB 图像最多 1000 次,如果在调用 ImageIO.read 之前将整个图像读入内存,则加载所用的时间会减少:
However I found that ImageIO.read(File)
quite slow on non-SSD drives (ie 500ms to 1 second). When testing NAS and HDD drives on my PC 4-6MB images called InputStream.read() up to 1000 times and that elapsed time for loads are reduced if entire image was read into memory before calling ImageIO.read:
static BufferedImage load(File f) throws IOException
{
byte[] bytes = Files.readAllBytes(f.toPath());
try (InputStream is = new ByteArrayInputStream(bytes))
{
return ImageIO.read(is);
}
}
这个解决方案可以稍微减慢 SSD 驱动器的访问时间(这对我来说不是 20 毫秒左右的问题),但在我的 PC 上,NAS/网络驱动器的增益幅度为 50-250 毫秒.
This solution can slow down access time on SSD drives a little (which was not an issue for me at ~ 20ms), but the margin of gain on NAS/network drive was 50-250ms on my PC.
显然,您观察到的时间取决于您的硬件、图像文件大小和类型,但在您的特定情况下可能值得尝试.
Obviously the timings you observe would depend on your hardware, image file size and types but it may be worth trying in your particular case.
如果您需要加载多个图像,您可以将文件 I/O 和 ImageIO 调用拆分为单独的线程以获得少量额外收益,但代价是额外的复杂性和内存占用.
If you need to load several images you can split the file I/O and ImageIO calls to separate threads for a small extra gain, but at cost of extra complexity and memory footprint.
这篇关于使用Java读取图像文件的有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!