Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 加载和重新调整图像大小的最快方法是什么?_Delphi_Image_Thumbnails_Filestream - Fatal编程技术网

Delphi 加载和重新调整图像大小的最快方法是什么?

Delphi 加载和重新调整图像大小的最快方法是什么?,delphi,image,thumbnails,filestream,Delphi,Image,Thumbnails,Filestream,我需要显示给定目录中图像的缩略图。在将图像加载到图像组件之前,我使用TFileStream读取图像文件。然后将位图大小调整为缩略图大小,并将其分配给TScrollBox上的TImage组件 它似乎工作正常,但对于较大的图像,速度会减慢很多 有没有更快的方法从磁盘加载(映像)文件并调整其大小 谢谢,彼得,不太好。你可以做的是在背景线程中调整它们的大小,并使用“占位符”图像,直到调整完毕。然后,我会将这些调整大小的图像保存到某种缓存文件中,以供以后处理(windows会这样做,并调用当前目录中的ca

我需要显示给定目录中图像的缩略图。在将图像加载到图像组件之前,我使用TFileStream读取图像文件。然后将位图大小调整为缩略图大小,并将其分配给TScrollBox上的TImage组件

它似乎工作正常,但对于较大的图像,速度会减慢很多

有没有更快的方法从磁盘加载(映像)文件并调整其大小


谢谢,彼得,不太好。你可以做的是在背景线程中调整它们的大小,并使用“占位符”图像,直到调整完毕。然后,我会将这些调整大小的图像保存到某种缓存文件中,以供以后处理(windows会这样做,并调用当前目录中的cache thumbs.db)


线程体系结构本身有几个选项。执行所有映像的单个线程,或者一个线程池,其中一个线程只知道如何处理单个映像。库甚至是另一种方式,它可以让事情变得相当简单。

我将补充skamradt的答案,尝试将其设计得尽可能快。为此,你应该

  • 优化I/O
  • 使用多个线程使用多个CPU内核,并在读取(或写入)文件时保持单个CPU内核工作
使用多线程意味着使用VCL类来调整大小是行不通的,因为VCL不是线程安全的,而且所有的黑客攻击都不能很好地扩展。有图像处理代码的链接

在使用多个线程时,不要导致多个并发I/O操作,这一点很重要。如果选择将缩略图像写回文件,那么一旦开始读取文件,就应该完全读取,一旦开始写入文件,也应该完全写入。交叉执行这两个操作将终止I/O,因为可能会导致硬盘磁头的大量查找操作

为了获得最佳结果,文件的读取(和写入)也不应该发生在应用程序的主(GUI)线程中。这将建议以下设计:

  • 让一个线程将文件读入TGraphic对象,并将其放入线程安全列表中
  • 让线程池等待原始大小的文件列表,让一个线程处理一个TGraphic对象,将其调整为另一个TGraphic对象,并将其添加到另一个线程安全列表
  • 为添加到列表中的每个缩略图通知GUI线程,以便显示
  • 如果要将缩略图写入文件,也可以在阅读线程中执行此操作(请参见上面的解释)
编辑:


在重读你的问题时,我注意到你可能只需要调整一幅图像的大小,在这种情况下,一条背景线当然就足够了。无论如何,我会把我的答案留在原地,也许有一天它会对其他人有用。这是我从我最近的一个项目中学到的,最终的程序可能需要更高的速度,但在高峰期只使用了大约75%的四核机器。将I/O与处理分离可能会产生不同。

我经常使用缩放比例为:=JS的TJPEGImage(在Delphi 7中)。这真的很快,因为JPEG反压缩可以跳过大量数据来填充宽度和高度仅为八分之一的位图


另一个选择是使用,它也非常快

我从事vision业务,我只需使用OpenGL将图像上传到GPU。(通常为每秒20 x 2048x2000x8bpp),每个纹理一个bmp,并让视频卡缩放(win32,Mike Lischke的opengl标题)

上传这样的图像需要5-10毫秒的时间,具体取决于视频卡(如果没有集成和nvidia 7300系列或更高版本,也可以使用最新的集成GPU)。缩放和显示成本为300美元。这意味着客户可以在不触摸应用程序的情况下疯狂地平移和缩放。我在它上面画了一个覆盖图(以前是一个tmetafile,但现在是自己的格式)

我最大的图片是4096x700x8bpp,显示和缩放时间不到30毫秒。(绿表8600)

该技术的一个限制是最大纹理大小。它可以通过将图片分割成多个纹理来解决,但我还没有费心,因为我用软件交付了系统

(一些典型尺寸: nv6x00系列:2k*2k但与GDI相比,上传几乎是收支平衡 nv7x00系列:4k*4k对于我来说是基准卡。GF7300的价格大约是20-40美元 nv8x00系列:8k*8k )

请注意,这可能并不适用于所有人。但是如果您幸运地指定了硬件限制,那么它可能会起作用。主要问题是像ThinkPad这样的笔记本电脑,它们的GPU比avg笔记本电脑要老,而avg笔记本电脑往往比台式电脑落后一代


我选择OpenGL而不是DirectX,因为它在时间上更静态,更容易找到与游戏无关的示例。

利用windows的功能创建缩略图。还记得在包含图像的文件夹中隐藏Thumbs.db文件吗

我已经用VB实现了类似的功能。我的软件能够在大约10秒钟内生成100个文件(混合大小)的缩略图


不过,我无法将其转换为Delphi。

试着看看:它非常擅长绘制东西,并且与位图配合使用效果非常好。它们是线程安全的,有很好的示例,而且完全免费。

这看起来不错。去年我非常想弄清楚这一点,但现在我不再太在意了。但我仍然可以使用TJPEGImage.Scale方法修复我的一些应用程序。ThanksMy应用程序现在使用占位符和线程(skamradt、mghie),它工作得非常好。根据Stijn Sanders的建议提取缩略图。非常感谢。不幸的是,AsyncCalls已停止(中断)。