我需要显示给定目录中图像的缩略图。在将图像加载到图像组件之前,我使用TFileStream读取图像文件。然后将位图调整为缩略图大小,并将其分配给TScrollBox上的TImage组件。
它似乎工作正常,但在较大的图像下会变慢很多。
有没有更快的方法从磁盘加载(图像)文件并调整它们的大小?
谢谢,皮特
发布于 2009-05-07 08:30:48
不怎么有意思。你可以做的是在后台线程中调整它们的大小,并使用“占位符”图像,直到完成大小调整。然后,我会将这些调整大小的图像保存到某种缓存文件中,以便稍后处理(windows会执行此操作,并调用当前目录中的缓存thumbs.db )。
关于线程架构本身,您有几个选择。一个处理所有图像的线程,或者一个线程池,其中一个线程只知道如何处理单个图像。AsyncCalls库甚至是另一种方式,它可以使事情变得相当简单。
发布于 2009-05-07 09:03:20
我将补充skamradt的答案,尝试将其设计为尽可能快。为此,您应该
多线程的使用意味着使用VCL类来调整大小是行不通的,因为VCL不是线程安全的,而且所有围绕它的hack都不能很好地扩展。efg's Computer Lab提供了图像处理代码的链接。
在使用多线程时,不要导致多个并发I/O操作,这一点很重要。如果你选择将缩略图写回文件,那么一旦你开始读取文件,你就应该完整地阅读它,一旦你开始写入文件,你也应该完整地写入它。交错这两个操作将杀死您的I/O,因为您可能会导致硬盘磁头的大量寻道操作。
为了获得最佳结果,文件的读取(和写入)也不应该发生在应用程序的主(GUI)线程中。这将建议使用以下设计:
,请参见上面的
编辑:
在重新阅读你的问题时,我注意到你可能只需要调整一个图像的大小,在这种情况下,一个背景线程当然就足够了。不管怎样,我会把我的答案留在原处,也许以后它会对其他人有用。这是我从我最近的一个项目中学到的,最终的程序可能需要更多的速度,但在高峰期只使用了大约75%的四核机器。将I/O从处理中解耦本可以使情况有所不同。
发布于 2009-05-07 09:32:30
我经常在Scale:=jsEighth中使用TJPEGImage (在Delphi7中)。这真的很快,因为JPEG解压缩可以跳过许多数据,以填充仅为宽度和高度的八分之一的位图。
另一种选择是使用shell's method to extract a thumbnail,这也是相当快的
https://stackoverflow.com/questions/835665
复制相似问题