近期项目中需要往java平台传输图片,直接使用QNetworkAccessManager和QHttpMultipart类即可,其他博文中有分享。
主要是平台接口对所传输图片有要求:需要包含GPS信息(经度、纬度、高度)。
Qt无法直接实现,查了很多资料,发现exiv2库可以使用,经过一番折腾后,最终成功向平台传输,在此做个记录。
需要库exiv2,已提供下载。
经度、纬度、高度的写入:
#include"exiv2/exiv2.hpp"
using namespace std;bool ImageAnalysis::AddExifGPSInfo(const QString &keyStr,const QString& value)
{QStringList tempList;QString tempValue;if(keyStr == "Exif.GPSInfo.GPSAltitude"){tempValue = AltitudeToExiivGps(value);}else{tempList = DegreeToDDMMSS(value);tempValue = DDMMSSToExivGps(tempList);}std::string _keyStr = keyStr.toStdString();std::string _value = tempValue.toStdString();Exiv2::ExifKey tmp = Exiv2::ExifKey(_keyStr);Exiv2::ExifData::iterator pos = m_ed.findKey(tmp);if (pos == m_ed.end()){Exiv2::URationalValue::AutoPtr rv(new Exiv2::URationalValue);rv->read(_value);Exiv2::ExifKey key = Exiv2::ExifKey(_keyStr);m_ed.add(key, rv.get());}else//exif有 key{Exiv2::Value::AutoPtr v = pos->getValue();//将值指针向下强制转换为其实际类型Exiv2::URationalValue* prv = dynamic_cast<Exiv2::URationalValue*>(v.release());if (prv == 0)return false;Exiv2::URationalValue::AutoPtr rv(prv);rv->read(_value);pos->setValue(rv.get());}WriteExifData();return true;
}bool ImageAnalysis::WriteExifData()
{if(m_imagePtr.get() != 0){m_imagePtr->setExifData(m_ed);m_imagePtr->writeMetadata();return true;}return false;
}// 初始化
ImageAnalysis::ImageAnalysis(QString imagePath, QObject *parent):m_imagePath(imagePath),QObject(parent)
{std::string temp = m_imagePath.toStdString();m_imagePtr = Exiv2::ImageFactory::open(temp);if (m_imagePtr.get() == nullptr){qDebug()<< "Read Exif Error.";return;}m_imagePtr->readMetadata();m_ed.clear();m_ed = m_imagePtr->exifData();
}
额外经度Ref、纬度Ref、高度Ref信息写入:
// GPSLongitudeRef写入
void ImageAnalysis::AddRefLongitude(const QString &WE)
{Exiv2::Value::AutoPtr longitudeRefValue = Exiv2::Value::create(Exiv2::asciiString);longitudeRefValue->read(WE.toStdString());m_ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLongitudeRef"), longitudeRefValue.release());
}// GPSLatitudeRef写入
void ImageAnalysis::AddRefLatitude(const QString &NS)
{Exiv2::Value::AutoPtr latitudeRefValue = Exiv2::Value::create(Exiv2::asciiString);latitudeRefValue->read(NS.toStdString());m_ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSLatitudeRef"), latitudeRefValue.release());
}// GPSAltitudeRef写入
void ImageAnalysis::AddRefAltitude(const QString &flag)
{Exiv2::Value::AutoPtr altitudeRefValue = Exiv2::Value::create(Exiv2::unsignedByte);altitudeRefValue->read(flag.toStdString());m_ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitudeRef"), altitudeRefValue.release());
}
功能调用过程:
{ImageAnalysis imageAnalysis;imageAnalysis.Reset(fileName); // jpg文件名设置imageAnalysis.AddExifGPSInfo(GPS_Longitude, lon); // 经度添加imageAnalysis.AddExifGPSInfo(GPS_Latitude, lat); // 纬度添加imageAnalysis.AddExifGPSInfo(GPS_Altitude, alt); // 高度添加imageAnalysis.AddRefLongitude("E"); // 经度Ref添加imageAnalysis.AddRefLatitude("W"); // 纬度Ref添加imageAnalysis.AddRefAltitude("0"); // 高度Ref添加imageAnalysis.WriteExifData(); // GPS信息保存
}
到此,大功告成!!!
验证一:系统中图片属性-详细信息中就有了GPS一栏:
验证二:使用Exif Pilot软件,可以看到更专业的信息: