2

我需要测试文件是 JPEG 还是 PNG,我不能相信文件扩展名,因为它可能是错误的。为此,我决定使用 GIL。

这是声明(和定义)的头文件boost::gil::png_read_dimensions。它明确指出boost::gil::png_read_dimensions “如果位置与有效的 PNG 文件不对应,则抛出 std::ios_base::failure”。事实上,这似乎与函数的实际行为相当。

问题在于boost::gil::jpeg_read_dimensions你可以在这里看到。它还明确指出“如果位置不对应于有效的 JPEG 文件,则抛出 std::ios_base::failure”。然而,情况似乎并非如此!不会抛出异常,而是libjpeg打印到 stdout 或 stderr 然后退出程序。

请参阅以下代码:

#include <iostream>
#include <string>

#include <boost/gil/extension/io/jpeg_io.hpp>
#include <boost/gil/extension/io/png_io.hpp>

using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ios_base;

namespace bg = boost::gil;

int main(int, char**) {
  const string not_jpeg_or_png ("image.gif");

  cout << "bg::png_read_dimensions:" << endl;
  try {
    bg::png_read_dimensions(not_jpeg_or_png);
  } catch(const ios_base::failure &ib_f) {
    cerr << "what: " << ib_f.what() << endl;
  }

  cout << "\nbg::jpeg_read_dimensions:" << endl;
  try {
    bg::jpeg_read_dimensions(not_jpeg_or_png);
  } catch(const ios_base::failure &ib_f) {
    cerr << "what: " << ib_f.what() << endl;
  }

  cout << "\nDone." << endl;

  return 0;
}

程序输出:

bg::png_read_dimensions:
what: png_check_validity: invalid png file: unspecified iostream_category error

bg::jpeg_read_dimensions:
Not a JPEG file: starts with 0x62 0x6c

请注意如何打印what: ... yadiyadiyada ...Done.不打印。

我尝试做} catch(...) {而不是} catch(const ios_base::failure &ib_f) {确保没有异常通过但没有成功。不会抛出异常!

我在这里错过了一些非常明显的东西......?难道我做错了什么?有解决方法吗?

4

2 回答 2

1

最简单的方法是读取文件的前几位,看看它们是否与文件类型的签名匹配。

89 50 4E 47 0D 0A 1A 0A => PNG

FF D8 FF => JPEG

于 2015-05-15T18:19:27.653 回答
0

我不明白为什么显然无法捕获抛出的异常。这可能是一个错误。

但是,为了完成我建议的任务

  • libmagic或者
  • identify(来自 ImageMagick)

这符合其他答案的建议。

这个答案包含一个如何使用 libmagic 的示例(通常存在于 linux 上,但可以在任何其他平台上构建和(静态)链接:

于 2015-05-15T17:49:45.320 回答