【问题标题】:Cannot use Boost GIL to detect image filetype (exception not caught)无法使用 Boost GIL 检测图像文件类型(未捕获异常)
【发布时间】:2015-05-16 02:53:09
【问题描述】:

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

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

问题在于boost::gil::jpeg_read_dimensions,您可以看到here。它还明确指出它“如果位置不对应于有效的 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 &amp;ib_f) { 来确保没有异常通过但没有成功。不会抛出异常!

我是否在这里遗漏了一些非常明显的东西......?难道我做错了什么?有解决办法吗?

【问题讨论】:

    标签: c++ boost detection image-formats boost-gil


    【解决方案1】:

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

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

    FF D8 FF => JPEG

    【讨论】:

    • 我试试看,谢谢你的建议。 “89 50 4E ...”;你已经把它写成十六进制对了,对吧?
    【解决方案2】:

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

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

    • libmagic
    • identify(来自 ImageMagick)

    这符合其他答案的建议。

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

    【讨论】:

    • 我会在 StackOverflow 上给这个问题一两天,如果到那时还没有给出令人满意的答案,我会看看我是否可以将它发布到 Boost Trac。如果我这样做了,我会确保在此处发布票证链接。
    • 我开了一张票here。我正在尝试自己研究它,因为我在相关代码中找到了这条注释:“// lbourdev:这会返回错误吗?您需要检查并抛出。检查所有其他可以返回错误的库方法状态...”... :)
    猜你喜欢
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2014-02-04
    • 2016-09-15
    相关资源
    最近更新 更多