近期项目中需要往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软件,可以看到更专业的信息: