2

我正在构建一个 iOS 应用程序,它可以拍照、修改图片并将 XMP 元数据嵌入到图片中。问题在于编写 XMP 部分。图片保存为 JPEG 后,我使用Exiv2重新打开图片,写入 XMP,然后重新保存 JPEG。这是我的示例代码:

Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(jpegUrl);
image->readMetadata();
Exiv2::XmpData &xmpData = image->xmpData();
if (xmpData.empty()) {
    cout<<"file XMP empty."<<endl;
}
else{
    cout<<"file XMP not empty."<<endl;
}

xmpData["Xmp.GPano.mycustomtag"] = "customString";

image->setXmpData(xmpData);
image->writeMetadata(); //Never crashes until here.

std::string xmpPacket;
if (0 != Exiv2::XmpParser::encode(xmpPacket, xmpData)) //Here is the problem!
{
    throw Exiv2::Error(1, "Failed to serialize XMP data");
    return;
}

断点

在我的 PC 上运行良好,使用 XCode 和 iOS 模拟器也运行良好。XMP 已正确写入 JPEG 文件。但是,当我在 iPhone 上测试时,它会抛出

警告:未编译 XMP 工具包支持。

并且 XMP 不存在。我怀疑 Exiv2 在我为 iOS 构建它时没有正确链接。这是我的做法:

  1. 下载并构建适用于所有拱门的Expat(i386 x86_64 armv7 armv7s arm64)。我使用此脚本进行构建,经过一些调整后它运行良好。我用 lipo 检查了生成的 libexpat.a 并且所有的拱门都在那里。请注意,如果启用了 XMP,Exiv2 需要 Expat。
  2. 使用此脚本并进行一些调整,为 iPhoneSimulator(i368 和 x86_64)构建 Exiv2 。在构建时,没有错误,正如我所说,一切正常。配置命令如下所示:./configure --host=x86_64-apple-darwin --prefix=$PREFIXDIR/iphonesim-build --disable-dependency-tracking --enable-static=yes --enable-shared=no --disable-dependency-tracking --enable-commercial --disable-nls --disable-lensdata --without-libiconv-prefix --without-zlib --with-expat=/Users/kevin/Downloads/expat-ios
  3. 但是,在为 iPhoneOS(armv7、armv7s 和 arm64)构建时出现错误:

libtool: link: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch armv7 -arch armv7s -arch arm64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk -mios-version-min=10.2 -o ../bin/exiv2 exiv2.o actions.o utils.o -Wl,-bind_at_load -L/Users/kevin/Downloads/expat-ios/lib -L/Users/kevin/Downloads/exiv2-ios/src/exiv2-0.25/xmpsdk/src ./.libs/libexiv2.a -liconv -lexpat -ldl Undefined symbols for architecture armv7: "_WXMPIterator_DecrementRefCount_1", referenced from: TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::operator=(TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&) in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) TXMPIterator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::~TXMPIterator() in libexiv2.a(xmp.o) Exiv2::XmpParser::decode(Exiv2::XmpData&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libexiv2.a(xmp.o)

并在一长串错误之后:

"MD5Init(MD5_CTX*)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) "MD5Final(unsigned char*, MD5_CTX*)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) "MD5Update(MD5_CTX*, unsigned char const*, unsigned int)", referenced from: Exiv2::Converter::computeExifDigest(bool) in libexiv2.a(convert.o) Exiv2::Converter::computeIptcDigest() in libexiv2.a(convert.o) ld: symbol(s) not found for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) make[1]: *** [exiv2] Error 1 make: *** [install] Error 2

因此,即使编译器构建并创建了 iPhoneOS 的库,Exiv2 也无法XmpParser::encode正确调用并崩溃。如果我删除该部分,它不会崩溃,但不会写入 XMP。

我的问题是:

  1. 如何为 iPhoneOS 架构正确构建 Exiv2?
  2. 是否有任何其他可能的原因导致在 iOS 中将 XMP 写入 JPEG 文件不起作用?
4

0 回答 0