如何在不加载完整文件的情况下检查文件是否为图像?有图像标题阅读库吗?

时间:2009-12-30 17:15:48

标签: c++ image qt file-io qimage

修改

对不起,我猜我的问题很模糊。我想有办法检查文件是否图像而不浪费时间加载整个图像,因为那时我可以稍后进行其余的加载。我不想只检查文件扩展名。

应用程序只是查看图像。通过“检查有效性”,我的意思是“检测并跳过非图像文件”也在目录中。如果像素数据损坏,我仍然希望将其视为图像。

我分配页码并配对这些图像。有些图像是单页左页或右页。有些图像很宽,是左右页面的“扩散”。例如,pagesAt(3)和pagesAt(4)可以返回相同的std ::对图像或同一宽图像的std ::对。

有时候,有一些奇怪的“瘦”图像,第一张图像将自己显示,类似于宽图像。一个例子是一个封面页。

不知道目录中的哪些文件是非图像意味着我无法自信地分配这些页码并将文件配对以进行显示。此外,用户可能决定跳转到页面X,当我稍后发现并删除非图像文件并相应地重新分配页码时,页面X可能看起来是不同的图像。

原始

如果重要,我正在使用Qt库中的c ++和QImage。

我正在遍历目录并在图像的路径上使用QImage构造函数。当然,这非常慢,使应用程序感觉无响应。但是,它确实允许我检测无效的图像文件并在早期忽略它们。

我只能在浏览目录时只保存图像的路径,并且只在需要时才加载它们,但后来我不知道图像是否无效。

我正在考虑将这两者结合起来。即,在遍历目录时,只读取图像的标题以检查有效性,然后在需要时加载图像数据。

所以,

只是加载图像标题比加载整个图像要快得多吗?或者正在做一些i / o来读取标题意味着我可能最终完成加载图像?稍后,我将解压缩档案中的图像,因此这也适用于解压缩标题与解压缩整个文件。

另外,我不知道如何加载/读取只是图像标题。是否有可以只读取图像标题的库?否则,我必须自己打开每个文件作为流和代码图像标题阅读器的所有文件类型。

5 个答案:

答案 0 :(得分:4)

Unix file工具(几乎永远存在)就是这样做的。它是一个简单的工具,它使用已知文件头和二进制签名的数据库来识别文件的类型(并可能提取一些简单的信息)。

数据库是一个简单的文本文件(为了提高效率而编译),它使用简单的结构化格式(man magic中记录)描述了大量的二进制文件格式。源位于/usr/share/file/magic(在Ubuntu中)。例如,PNG文件格式的条目如下所示:

0       string          \x89PNG\x0d\x0a\x1a\x0a         PNG image
!:mime  image/png
>16     belong          x               \b, %ld x
>20     belong          x               %ld,
>24     byte            x               %d-bit
>25     byte            0               grayscale,
>25     byte            2               \b/color RGB,
>25     byte            3               colormap,
>25     byte            4               gray+alpha,
>25     byte            6               \b/color RGBA,
>28     byte            0               non-interlaced
>28     byte            1               interlaced

您可以仅提取图像文件类型的签名,并构建自己的“嗅探器”,甚至可以使用file工具中的解析器(似乎是BSD许可的)。

答案 1 :(得分:3)

只需添加我的2美分:您可以使用QImageReader获取有关图像文件的信息,而无需实际加载文件。

例如,使用.format方法,您可以检查文件的图像格式。

来自官方Qt doc(http://qt-project.org/doc/qt-4.8/qimagereader.html#format):

  

返回QImageReader用于读取图像的格式。你可以打电话   将此设备分配给读卡器以确定后,此功能   设备的格式。例如:QImageReader reader(“image.png”);   // reader.format()==“png”如果读者无法从中读取任何图像   设备(例如,那里没有图像,或图像已经存在   已读过),或者如果格式不受支持,此函数返回一个   空QByteArray()。

答案 2 :(得分:0)

我不知道只是加载标题的答案,它可能取决于您尝试加载的图像类型。您可以考虑使用Qt :: Concurrent来完成图像,同时允许程序的其余部分继续,如果可能的话。在这种情况下,您可能最初将所有条目表示为未知状态,然后在验证完成后更改为图像或非图像。

答案 3 :(得分:0)

如果您正在谈论一般的图像文件,而不仅仅是特定的格式,我愿意打赌有些情况下图像标题有效,但图像数据不是。你还没有说过你的应用程序,你有没有办法在后台添加一个可以在ram中保留一些图像的线程,并根据用户下一步加载的内容交换它们? IE:幻灯片放映应用会在当前版本的前后加载1或2张图片。或者可能在图像名称旁边显示一个问号,直到后台线程可以验证数据的有效性。

答案 4 :(得分:0)

虽然在本地文件系统上打开和读取文件的标题不应该太昂贵,但如果文件位于远程(联网)文件系统上,则可能会很昂贵。更糟糕的是,如果您访问使用hierarchical storage management保存的文件,阅读文件可能会非常昂贵。

如果此应用仅适合您,那么您可以决定不担心这些问题。但是,如果您要向公众发布您的应用程序,在您必须之前阅读该文件将导致某些用户出现问题。

Raymond Chen在他的博客The Old New Thing上写了一篇关于此事的文章。