【问题标题】:Read metadata from a PNG file with imagemagick++使用 imagemagick++ 从 PNG 文件中读取元数据
【发布时间】:2021-01-06 18:52:19
【问题描述】:

我想使用 imagemagick++ API 来执行此操作(如主题所示)。我特别想阅读(数码单反相机)拍摄时使用的焦距。 [EDIT]这是处理图像的程序的一部分[END EDIT]

我知道我可以通过系统调用,调用命令identify -verbose <image_filename> 来做到这一点(例如,使用popen 以便我可以读取输出并查找包含FocalLengthIn35mmFilm 的行)。但这很恶心,原因有两个:

  • 这只是粗暴和低效。
  • identify 是一个 ImageMagick 实用程序,所以如果该命令可以执行此操作,那么我应该可以使用 ImageMagick 的 API 执行此操作。

请注意,正如主题所说,我正在处理 PNG 文件;但是,可以使用任何无损图像格式的解决方案将是首选。

【问题讨论】:

  • 如果您只想要元数据而不是整个 Magick++ 开发套件及其图像处理功能,您可能会发现exiv2 重量更轻...exiv2.org/examples.html
  • 好点,我在我的 OP 中没有明确说明(我只是编辑它以表明我确实需要操纵图像,这就是我使用 imagemagick 的 API 的原因)跨度>
  • 显然我不知道您需要对图像进行多少处理,但您可能会发现 CImg cimg.eu 中相当全面的功能足以满足您的需求而且重量很轻,因为它只是一个没有要链接的库的包含文件。 CImg 结合 exiv2 可能是一种解决方案。请不要误解我的意思,我并不是要以任何方式建议您不要使用 Magick++,我只是在探索其他可能性。
  • 我正在做的任何“繁重”处理都发生在我可以访问作为 (x,y) 函数的像素值之后;当然,我还需要从 PNG 文件中读取并写入生成的 PNG 输出。就图像库而言,相当基本。但是,我要说,虽然指针很受赞赏(我一定会研究这个CImg库),惯性是一个非常强大的东西,而且我的程序的基础版本已经使用了imgmagick++; CImg 不能解决手头的问题(因为我必须另外使用 exiv2),所以我现在会坚持使用 imgmagick++。
  • FWIW,我已经添加了popen/identify -verbose ...代码,并在我当前的程序“开发分支”中成功获得了焦距;我非常想通过 API 来实现它;但更糟糕的是,我可以用popen / identify -verbose 方法留下它,即使我觉得它很丑(它有效)

标签: imagemagick png metadata


【解决方案1】:

ImageMagick 不是 EXIF 编辑器,因此最好的选择是将配置文件 EXIF 有效负载转储到 libexif API。但是,如果您只是在某个值上达到峰值,您可以使用 ImageMagick 的 percent escape 机制来检索一个值。

例如:

#include <iostream>
#include <string>
#include <Magick++.h>

using namespace Magick;

int main()
{
    InitializeMagick((const char *)nullptr);
    Image img("DSCF2763.JPG");
    Blob data;
    MagickCore::SetImageOption(img.imageInfo(), "format", "%[EXIF:FocalLengthIn35mmFilm]");
    img.write(&data, "INFO");
    std::string value((const char *)data.data(), data.length());
    std::cout << value << std::endl;
}

以上与CLI命令相同:

convert DSCF2763.JPG -define "format=%[EXIF:FocalLengthIn35mmFilm]" info:

更新

更简单的方法是使用Magick::Image.attribute()

#include <iostream>
#include <string>
#include <Magick++.h>

using namespace Magick;

int main()
{
    InitializeMagick((const char *)nullptr);
    Image img("DSCF2763.JPG");
    std::string value = img.attribute("EXIF:FocalLengthIn35mmFilm");
    std::cout << value << std::endl;
}

【讨论】:

  • 第二个版本看起来更干净(反正更简单)。起初,我认为它可能不起作用,因为 EXIF(我认为 EXIF 是一种特定于 JPEG 的东西),但我只是尝试了一下,它就像一个魅力!
猜你喜欢
  • 1970-01-01
  • 2014-05-25
  • 2019-07-14
  • 2011-01-12
  • 2016-04-29
  • 2020-01-10
  • 2012-12-14
  • 2011-08-21
  • 2021-08-23
相关资源
最近更新 更多