mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2026-05-25 13:08:28 -04:00
EXIF improvements and bugfixes
- Fixes a writing issue for float values less than 1 - Fixes a missing definition of `EXIF_DATETIMEDIGITIZED` tag - Adds support for some common camera shot metadata - Adds missing metadata to writing tests The following plugins automatically gain support for the new metadata: AVIF, IFF, HEIF, JXL, JXR, PSD and TGA (V2E). The new metadata added with this patch is usually saved by smartphones (e.g. iPhone or Google Pixel).
This commit is contained in:
23
README.md
23
README.md
@@ -155,8 +155,31 @@ About the image:
|
|||||||
- `Owner`: Name of the owner of the image.
|
- `Owner`: Name of the owner of the image.
|
||||||
- `Software`: Name and version number of the software package(s) used to
|
- `Software`: Name and version number of the software package(s) used to
|
||||||
create the image.
|
create the image.
|
||||||
|
- `Speed`: Floating-point number indicating the speed of GPS receiver
|
||||||
|
movement in Km/h (e.g. 30.2).
|
||||||
- `Title`: The title of the image.
|
- `Title`: The title of the image.
|
||||||
|
|
||||||
|
About the shot:
|
||||||
|
- `DigitalZoomRatio`: Floating-point number indicating the digital zoom ratio
|
||||||
|
when the image was shot.
|
||||||
|
- `ExposureMode`: Integer number indicating the exposure mode set when the
|
||||||
|
image was shot as reported in the EXIF specifications.
|
||||||
|
- `ExposureProgram`: Integer number indicating the class of the program used
|
||||||
|
by the camera to set exposure when the picture is taken as reported in the
|
||||||
|
EXIF specifications.
|
||||||
|
- `ExposureTime`: Floating-point number indicating the exposure time,
|
||||||
|
given in seconds (s).
|
||||||
|
- `Flash`: Integer number indicating the status of flash when the image
|
||||||
|
was shot as reported in the EXIF specifications.
|
||||||
|
- `FNumber`: Floating-point number indicating the F number.
|
||||||
|
- `FocalLength`: Floating-point number indicating the actual focal length
|
||||||
|
of the lens, in millimeters (mm).
|
||||||
|
- `ISOSpeedRatings`: Integer number indicating the sensitivity of the camera
|
||||||
|
or input device when the image was shot as reported in the EXIF
|
||||||
|
specifications.
|
||||||
|
- `WhiteBalance`: Integer number indicating the white balance mode set when
|
||||||
|
the image was shot as reported in the EXIF specifications.
|
||||||
|
|
||||||
About the camera:
|
About the camera:
|
||||||
- `Manufacturer`: The manufacturer of the recording equipment.
|
- `Manufacturer`: The manufacturer of the recording equipment.
|
||||||
- `Model`: The model name or model number of the recording equipment.
|
- `Model`: The model name or model number of the recording equipment.
|
||||||
|
|||||||
@@ -13,14 +13,18 @@
|
|||||||
"key" : "ModificationDate",
|
"key" : "ModificationDate",
|
||||||
"value" : "2025-02-14T15:58:44+01:00"
|
"value" : "2025-02-14T15:58:44+01:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key" : "Software" ,
|
|
||||||
"value" : "Adobe Photoshop 26.2 (Windows)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key" : "Altitude",
|
"key" : "Altitude",
|
||||||
"value" : "34"
|
"value" : "34"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key" : "Title",
|
||||||
|
"value" : "A test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Software",
|
||||||
|
"value" : "KImageFormats write test"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key" : "Author",
|
"key" : "Author",
|
||||||
"value" : "KDE Project"
|
"value" : "KDE Project"
|
||||||
@@ -45,6 +49,10 @@
|
|||||||
"key" : "LensModel",
|
"key" : "LensModel",
|
||||||
"value" : "A1234"
|
"value" : "A1234"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensSerialNumber",
|
||||||
|
"value" : "S/N:1234567"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key" : "Longitude",
|
"key" : "Longitude",
|
||||||
"value" : "10.9254"
|
"value" : "10.9254"
|
||||||
@@ -56,6 +64,50 @@
|
|||||||
{
|
{
|
||||||
"key" : "Model",
|
"key" : "Model",
|
||||||
"value" : "KImageFormats"
|
"value" : "KImageFormats"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "SerialNumber",
|
||||||
|
"value" : "S/N:7654321"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Speed",
|
||||||
|
"value" : "13.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "DigitalZoomRatio",
|
||||||
|
"value" : "3.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureMode",
|
||||||
|
"value" : "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureProgram",
|
||||||
|
"value" : "6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureTime",
|
||||||
|
"value" : "0.004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Flash",
|
||||||
|
"value" : "16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "FNumber",
|
||||||
|
"value" : "1.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "FocalLength",
|
||||||
|
"value" : "5.96"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ISOSpeedRatings",
|
||||||
|
"value" : "50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "WhiteBalance",
|
||||||
|
"value" : "1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resolution" : {
|
"resolution" : {
|
||||||
|
|||||||
@@ -41,6 +41,10 @@
|
|||||||
"key" : "LensModel",
|
"key" : "LensModel",
|
||||||
"value" : "A1234"
|
"value" : "A1234"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key" : "LensSerialNumber",
|
||||||
|
"value" : "S/N:1234567"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key" : "Longitude",
|
"key" : "Longitude",
|
||||||
"value" : "10.9254"
|
"value" : "10.9254"
|
||||||
@@ -52,6 +56,50 @@
|
|||||||
{
|
{
|
||||||
"key" : "Model",
|
"key" : "Model",
|
||||||
"value" : "KImageFormats"
|
"value" : "KImageFormats"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "SerialNumber",
|
||||||
|
"value" : "S/N:7654321"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Speed",
|
||||||
|
"value" : "13.2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "DigitalZoomRatio",
|
||||||
|
"value" : "3.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureMode",
|
||||||
|
"value" : "2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureProgram",
|
||||||
|
"value" : "6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ExposureTime",
|
||||||
|
"value" : "0.004"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "Flash",
|
||||||
|
"value" : "16"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "FNumber",
|
||||||
|
"value" : "1.6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "FocalLength",
|
||||||
|
"value" : "5.96"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "ISOSpeedRatings",
|
||||||
|
"value" : "50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key" : "WhiteBalance",
|
||||||
|
"value" : "1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"resolution" : {
|
"resolution" : {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ void setOptionalInfo(QImage &image, const QString &suffix)
|
|||||||
|
|
||||||
// Set metadata
|
// Set metadata
|
||||||
auto meta = obj.value("metadata").toArray();
|
auto meta = obj.value("metadata").toArray();
|
||||||
for (auto jv : meta) {
|
for (auto &&jv : meta) {
|
||||||
auto obj = jv.toObject();
|
auto obj = jv.toObject();
|
||||||
auto key = obj.value("key").toString();
|
auto key = obj.value("key").toString();
|
||||||
auto val = obj.value("value").toString();
|
auto val = obj.value("value").toString();
|
||||||
@@ -106,7 +106,7 @@ bool checkOptionalInfo(QImage &image, const QString &suffix)
|
|||||||
|
|
||||||
// Test metadata
|
// Test metadata
|
||||||
auto meta = obj.value("metadata").toArray();
|
auto meta = obj.value("metadata").toArray();
|
||||||
for (auto jv : meta) {
|
for (auto &&jv : meta) {
|
||||||
auto obj = jv.toObject();
|
auto obj = jv.toObject();
|
||||||
auto key = obj.value("key").toString();
|
auto key = obj.value("key").toString();
|
||||||
auto val = obj.value("value").toString();
|
auto val = obj.value("value").toString();
|
||||||
|
|||||||
@@ -36,17 +36,26 @@
|
|||||||
#define TIFF_VAL_URES_CENTIMETER 3
|
#define TIFF_VAL_URES_CENTIMETER 3
|
||||||
|
|
||||||
// EXIF 3 specs
|
// EXIF 3 specs
|
||||||
|
#define EXIF_EXPOSURETIME 0x829A
|
||||||
|
#define EXIF_FNUMBER 0x829D
|
||||||
#define EXIF_EXIFIFD 0x8769
|
#define EXIF_EXIFIFD 0x8769
|
||||||
|
#define EXIF_EXPOSUREPROGRAM 0x8822
|
||||||
#define EXIF_GPSIFD 0x8825
|
#define EXIF_GPSIFD 0x8825
|
||||||
|
#define EXIF_ISOSPEEDRATINGS 0x8827
|
||||||
#define EXIF_EXIFVERSION 0x9000
|
#define EXIF_EXIFVERSION 0x9000
|
||||||
#define EXIF_DATETIMEORIGINAL 0x9003
|
#define EXIF_DATETIMEORIGINAL 0x9003
|
||||||
#define EXIF_DATETIMEDIGITIZED 0x9004
|
#define EXIF_DATETIMEDIGITIZED 0x9004
|
||||||
#define EXIF_OFFSETTIME 0x9010
|
#define EXIF_OFFSETTIME 0x9010
|
||||||
#define EXIF_OFFSETTIMEORIGINAL 0x9011
|
#define EXIF_OFFSETTIMEORIGINAL 0x9011
|
||||||
#define EXIF_OFFSETTIMEDIGITIZED 0x9012
|
#define EXIF_OFFSETTIMEDIGITIZED 0x9012
|
||||||
|
#define EXIF_FLASH 0x9209
|
||||||
|
#define EXIF_FOCALLENGTH 0x920A
|
||||||
#define EXIF_COLORSPACE 0xA001
|
#define EXIF_COLORSPACE 0xA001
|
||||||
#define EXIF_PIXELXDIM 0xA002
|
#define EXIF_PIXELXDIM 0xA002
|
||||||
#define EXIF_PIXELYDIM 0xA003
|
#define EXIF_PIXELYDIM 0xA003
|
||||||
|
#define EXIF_EXPOSUREMODE 0xA402
|
||||||
|
#define EXIF_WHITEBALANCE 0xA403
|
||||||
|
#define EXIF_DIGITALZOOMRATIO 0xA404
|
||||||
#define EXIF_IMAGEUNIQUEID 0xA420
|
#define EXIF_IMAGEUNIQUEID 0xA420
|
||||||
#define EXIF_BODYSERIALNUMBER 0xA431
|
#define EXIF_BODYSERIALNUMBER 0xA431
|
||||||
#define EXIF_LENSMAKE 0xA433
|
#define EXIF_LENSMAKE 0xA433
|
||||||
@@ -64,6 +73,8 @@
|
|||||||
#define GPS_LONGITUDE 4
|
#define GPS_LONGITUDE 4
|
||||||
#define GPS_ALTITUDEREF 5
|
#define GPS_ALTITUDEREF 5
|
||||||
#define GPS_ALTITUDE 6
|
#define GPS_ALTITUDE 6
|
||||||
|
#define GPS_SPEEDREF 12
|
||||||
|
#define GPS_SPEED 13
|
||||||
#define GPS_IMGDIRECTIONREF 16
|
#define GPS_IMGDIRECTIONREF 16
|
||||||
#define GPS_IMGDIRECTION 17
|
#define GPS_IMGDIRECTION 17
|
||||||
#define EXIF_TAG_VALUE(n, byteSize) (((n) << 6) | ((byteSize) & 0x3F))
|
#define EXIF_TAG_VALUE(n, byteSize) (((n) << 6) | ((byteSize) & 0x3F))
|
||||||
@@ -123,16 +134,25 @@ static const KnownTags staticTagTypes = {
|
|||||||
TagInfo(TIFF_ARTIST, ExifTagType::Utf8),
|
TagInfo(TIFF_ARTIST, ExifTagType::Utf8),
|
||||||
TagInfo(TIFF_DATETIME, ExifTagType::Ascii),
|
TagInfo(TIFF_DATETIME, ExifTagType::Ascii),
|
||||||
TagInfo(TIFF_COPYRIGHT, ExifTagType::Utf8),
|
TagInfo(TIFF_COPYRIGHT, ExifTagType::Utf8),
|
||||||
|
TagInfo(EXIF_EXPOSURETIME, ExifTagType::Rational),
|
||||||
|
TagInfo(EXIF_FNUMBER, ExifTagType::Rational),
|
||||||
TagInfo(EXIF_EXIFIFD, ExifTagType::Long),
|
TagInfo(EXIF_EXIFIFD, ExifTagType::Long),
|
||||||
|
TagInfo(EXIF_EXPOSUREPROGRAM, ExifTagType::Short),
|
||||||
TagInfo(EXIF_GPSIFD, ExifTagType::Long),
|
TagInfo(EXIF_GPSIFD, ExifTagType::Long),
|
||||||
|
TagInfo(EXIF_ISOSPEEDRATINGS, ExifTagType::Short),
|
||||||
TagInfo(EXIF_DATETIMEORIGINAL, ExifTagType::Ascii),
|
TagInfo(EXIF_DATETIMEORIGINAL, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_OFFSETTIMEDIGITIZED, ExifTagType::Ascii),
|
TagInfo(EXIF_DATETIMEDIGITIZED, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_OFFSETTIME, ExifTagType::Ascii),
|
TagInfo(EXIF_OFFSETTIME, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_OFFSETTIMEORIGINAL, ExifTagType::Ascii),
|
TagInfo(EXIF_OFFSETTIMEORIGINAL, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_OFFSETTIMEDIGITIZED, ExifTagType::Ascii),
|
TagInfo(EXIF_OFFSETTIMEDIGITIZED, ExifTagType::Ascii),
|
||||||
|
TagInfo(EXIF_FLASH, ExifTagType::Short),
|
||||||
|
TagInfo(EXIF_FOCALLENGTH, ExifTagType::Rational),
|
||||||
TagInfo(EXIF_COLORSPACE, ExifTagType::Short),
|
TagInfo(EXIF_COLORSPACE, ExifTagType::Short),
|
||||||
TagInfo(EXIF_PIXELXDIM, ExifTagType::Long),
|
TagInfo(EXIF_PIXELXDIM, ExifTagType::Long),
|
||||||
TagInfo(EXIF_PIXELYDIM, ExifTagType::Long),
|
TagInfo(EXIF_PIXELYDIM, ExifTagType::Long),
|
||||||
|
TagInfo(EXIF_EXPOSUREMODE, ExifTagType::Short),
|
||||||
|
TagInfo(EXIF_WHITEBALANCE, ExifTagType::Short),
|
||||||
|
TagInfo(EXIF_DIGITALZOOMRATIO, ExifTagType::Rational),
|
||||||
TagInfo(EXIF_IMAGEUNIQUEID, ExifTagType::Ascii),
|
TagInfo(EXIF_IMAGEUNIQUEID, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_BODYSERIALNUMBER, ExifTagType::Ascii),
|
TagInfo(EXIF_BODYSERIALNUMBER, ExifTagType::Ascii),
|
||||||
TagInfo(EXIF_LENSMAKE, ExifTagType::Utf8),
|
TagInfo(EXIF_LENSMAKE, ExifTagType::Utf8),
|
||||||
@@ -155,6 +175,8 @@ static const KnownTags staticGpsTagTypes = {
|
|||||||
TagInfo(GPS_LONGITUDE, ExifTagType::Rational),
|
TagInfo(GPS_LONGITUDE, ExifTagType::Rational),
|
||||||
TagInfo(GPS_ALTITUDEREF, ExifTagType::Byte),
|
TagInfo(GPS_ALTITUDEREF, ExifTagType::Byte),
|
||||||
TagInfo(GPS_ALTITUDE, ExifTagType::Rational),
|
TagInfo(GPS_ALTITUDE, ExifTagType::Rational),
|
||||||
|
TagInfo(GPS_SPEEDREF, ExifTagType::Ascii),
|
||||||
|
TagInfo(GPS_SPEED, ExifTagType::Rational),
|
||||||
TagInfo(GPS_IMGDIRECTIONREF, ExifTagType::Ascii),
|
TagInfo(GPS_IMGDIRECTIONREF, ExifTagType::Ascii),
|
||||||
TagInfo(GPS_IMGDIRECTION, ExifTagType::Rational)
|
TagInfo(GPS_IMGDIRECTION, ExifTagType::Rational)
|
||||||
};
|
};
|
||||||
@@ -317,7 +339,7 @@ static void writeList(QDataStream &ds, const QVariant &value)
|
|||||||
inline qint32 rationalPrecision(double v)
|
inline qint32 rationalPrecision(double v)
|
||||||
{
|
{
|
||||||
v = qAbs(v);
|
v = qAbs(v);
|
||||||
return 8 - qBound(0, v < 1 ? 8 : int(std::log10(v)), 8);
|
return v < 1 ? 8 : 8 - qBound(0, int(std::log10(v)), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -884,7 +906,7 @@ QDateTime MicroExif::dateTime() const
|
|||||||
auto ofTag = exifString(EXIF_OFFSETTIME);
|
auto ofTag = exifString(EXIF_OFFSETTIME);
|
||||||
if (dt.isValid() && !ofTag.isEmpty())
|
if (dt.isValid() && !ofTag.isEmpty())
|
||||||
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
||||||
return(dt);
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroExif::setDateTime(const QDateTime &dt)
|
void MicroExif::setDateTime(const QDateTime &dt)
|
||||||
@@ -904,7 +926,7 @@ QDateTime MicroExif::dateTimeOriginal() const
|
|||||||
auto ofTag = exifString(EXIF_OFFSETTIMEORIGINAL);
|
auto ofTag = exifString(EXIF_OFFSETTIMEORIGINAL);
|
||||||
if (dt.isValid() && !ofTag.isEmpty())
|
if (dt.isValid() && !ofTag.isEmpty())
|
||||||
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
||||||
return(dt);
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroExif::setDateTimeOriginal(const QDateTime &dt)
|
void MicroExif::setDateTimeOriginal(const QDateTime &dt)
|
||||||
@@ -924,7 +946,7 @@ QDateTime MicroExif::dateTimeDigitized() const
|
|||||||
auto ofTag = exifString(EXIF_OFFSETTIMEDIGITIZED);
|
auto ofTag = exifString(EXIF_OFFSETTIMEDIGITIZED);
|
||||||
if (dt.isValid() && !ofTag.isEmpty())
|
if (dt.isValid() && !ofTag.isEmpty())
|
||||||
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(timeOffset(ofTag) * 60));
|
||||||
return(dt);
|
return dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroExif::setDateTimeDigitized(const QDateTime &dt)
|
void MicroExif::setDateTimeDigitized(const QDateTime &dt)
|
||||||
@@ -966,6 +988,138 @@ void MicroExif::setUniqueId(const QUuid &uuid)
|
|||||||
setExifString(EXIF_IMAGEUNIQUEID, uuid.toString(QUuid::WithoutBraces).replace(QStringLiteral("-"), QString()));
|
setExifString(EXIF_IMAGEUNIQUEID, uuid.toString(QUuid::WithoutBraces).replace(QStringLiteral("-"), QString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double MicroExif::digitalZoomRatio() const
|
||||||
|
{
|
||||||
|
if (!m_exifTags.contains(EXIF_DIGITALZOOMRATIO))
|
||||||
|
return qQNaN();
|
||||||
|
return m_exifTags.value(EXIF_DIGITALZOOMRATIO).toDouble();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setDigitalZoomRatio(double zoom)
|
||||||
|
{
|
||||||
|
if (qIsNaN(zoom))
|
||||||
|
m_exifTags.remove(EXIF_DIGITALZOOMRATIO);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_DIGITALZOOMRATIO, zoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 MicroExif::isoSpeedRatings() const
|
||||||
|
{
|
||||||
|
return quint16(m_exifTags.value(EXIF_ISOSPEEDRATINGS).toUInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setIsoSpeedRatings(quint16 iso)
|
||||||
|
{
|
||||||
|
if (iso == 0)
|
||||||
|
m_exifTags.remove(EXIF_ISOSPEEDRATINGS);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_ISOSPEEDRATINGS, iso);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExposureMode MicroExif::exposureMode() const
|
||||||
|
{
|
||||||
|
auto ok = false;
|
||||||
|
auto v = m_exifTags.value(EXIF_EXPOSUREMODE).toUInt(&ok);
|
||||||
|
return ok ? ExposureMode(v) : ExposureMode::NotSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setExposureMode(const ExposureMode &em)
|
||||||
|
{
|
||||||
|
if (em == ExposureMode::NotSet)
|
||||||
|
m_exifTags.remove(EXIF_EXPOSUREMODE);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_EXPOSUREMODE, quint16(em));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExposureProgram MicroExif::exposureProgram() const
|
||||||
|
{
|
||||||
|
auto ok = false;
|
||||||
|
auto v = m_exifTags.value(EXIF_EXPOSUREPROGRAM).toUInt(&ok);
|
||||||
|
return ok ? ExposureProgram(v) : ExposureProgram::NotSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setExposureProgram(const ExposureProgram &ep)
|
||||||
|
{
|
||||||
|
if (ep == ExposureProgram::NotSet)
|
||||||
|
m_exifTags.remove(EXIF_EXPOSUREPROGRAM);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_EXPOSUREPROGRAM, quint16(ep));
|
||||||
|
}
|
||||||
|
|
||||||
|
double MicroExif::exposureTime() const
|
||||||
|
{
|
||||||
|
if (!m_exifTags.contains(EXIF_EXPOSURETIME))
|
||||||
|
return qQNaN();
|
||||||
|
return m_exifTags.value(EXIF_EXPOSURETIME).toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setExposureTime(double et)
|
||||||
|
{
|
||||||
|
if (qIsNaN(et))
|
||||||
|
m_exifTags.remove(EXIF_EXPOSURETIME);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_EXPOSURETIME, et);
|
||||||
|
}
|
||||||
|
|
||||||
|
double MicroExif::fNumber() const
|
||||||
|
{
|
||||||
|
if (!m_exifTags.contains(EXIF_FNUMBER))
|
||||||
|
return qQNaN();
|
||||||
|
return m_exifTags.value(EXIF_FNUMBER).toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setFNumber(double f)
|
||||||
|
{
|
||||||
|
if (qIsNaN(f))
|
||||||
|
m_exifTags.remove(EXIF_FNUMBER);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_FNUMBER, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
double MicroExif::focalLength() const
|
||||||
|
{
|
||||||
|
if (!m_exifTags.contains(EXIF_FOCALLENGTH))
|
||||||
|
return qQNaN();
|
||||||
|
return m_exifTags.value(EXIF_FOCALLENGTH).toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setFocalLength(double fl)
|
||||||
|
{
|
||||||
|
if (qIsNaN(fl))
|
||||||
|
m_exifTags.remove(EXIF_FOCALLENGTH);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_FOCALLENGTH, fl);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashFlags MicroExif::flash() const
|
||||||
|
{
|
||||||
|
return FlashFlags(m_exifTags.value(EXIF_FLASH).toUInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setFlash(const FlashFlags &flash)
|
||||||
|
{
|
||||||
|
if (flash == Flash::NotSet)
|
||||||
|
m_exifTags.remove(EXIF_FLASH);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_FLASH, quint16(flash));
|
||||||
|
}
|
||||||
|
|
||||||
|
WhiteBalance MicroExif::whiteBalance() const
|
||||||
|
{
|
||||||
|
auto ok = false;
|
||||||
|
auto v = m_exifTags.value(EXIF_WHITEBALANCE).toUInt(&ok);
|
||||||
|
return ok ? WhiteBalance(v) : WhiteBalance::NotSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setWhiteBalance(const WhiteBalance &wb)
|
||||||
|
{
|
||||||
|
if (wb == WhiteBalance::NotSet)
|
||||||
|
m_exifTags.remove(EXIF_WHITEBALANCE);
|
||||||
|
else
|
||||||
|
m_exifTags.insert(EXIF_WHITEBALANCE, quint16(wb));
|
||||||
|
}
|
||||||
|
|
||||||
double MicroExif::latitude() const
|
double MicroExif::latitude() const
|
||||||
{
|
{
|
||||||
auto ref = gpsString(GPS_LATITUDEREF).toUpper();
|
auto ref = gpsString(GPS_LATITUDEREF).toUpper();
|
||||||
@@ -1045,6 +1199,30 @@ void MicroExif::setAltitude(double meters)
|
|||||||
m_gpsTags.insert(GPS_ALTITUDE, meters);
|
m_gpsTags.insert(GPS_ALTITUDE, meters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double MicroExif::imageSpeed() const
|
||||||
|
{
|
||||||
|
if (!m_gpsTags.contains(GPS_SPEED))
|
||||||
|
return qQNaN();
|
||||||
|
auto ref = gpsString(GPS_SPEEDREF).toUpper();
|
||||||
|
auto speed = m_gpsTags.value(GPS_SPEED).toDouble();
|
||||||
|
if (ref == QStringLiteral("M"))
|
||||||
|
speed *= 1.60934;
|
||||||
|
else if (ref == QStringLiteral("N"))
|
||||||
|
speed *= 1.852;
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MicroExif::setImageSpeed(double kmh)
|
||||||
|
{
|
||||||
|
if (qIsNaN(kmh)) {
|
||||||
|
m_gpsTags.remove(GPS_SPEEDREF);
|
||||||
|
m_gpsTags.remove(GPS_SPEED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_gpsTags.insert(GPS_SPEEDREF, QStringLiteral("K"));
|
||||||
|
m_gpsTags.insert(GPS_SPEED, kmh);
|
||||||
|
}
|
||||||
|
|
||||||
double MicroExif::imageDirection(bool *isMagnetic) const
|
double MicroExif::imageDirection(bool *isMagnetic) const
|
||||||
{
|
{
|
||||||
auto tmp = false;
|
auto tmp = false;
|
||||||
@@ -1191,6 +1369,58 @@ void MicroExif::updateImageMetadata(QImage &targetImage, bool replaceExisting) c
|
|||||||
if (!qIsNaN(v))
|
if (!qIsNaN(v))
|
||||||
targetImage.setText(QStringLiteral(META_KEY_DIRECTION), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
targetImage.setText(QStringLiteral(META_KEY_DIRECTION), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
}
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_SPEED)).isEmpty()) {
|
||||||
|
auto v = imageSpeed();
|
||||||
|
if (!qIsNaN(v))
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_SPEED), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
// shot info
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_DIGITALZOOMRATIO)).isEmpty()) {
|
||||||
|
auto v = digitalZoomRatio();
|
||||||
|
if (!qIsNaN(v))
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_DIGITALZOOMRATIO), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_EXPOSUREMODE)).isEmpty()) {
|
||||||
|
auto v = exposureMode();
|
||||||
|
if (v != ExposureMode::NotSet)
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_EXPOSUREMODE), QStringLiteral("%1").arg(quint16(v)));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_EXPOSUREPROGRAM)).isEmpty()) {
|
||||||
|
auto v = exposureProgram();
|
||||||
|
if (v != ExposureProgram::NotSet)
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_EXPOSUREPROGRAM), QStringLiteral("%1").arg(quint16(v)));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_EXPOSURETIME)).isEmpty()) {
|
||||||
|
auto v = exposureTime();
|
||||||
|
if (!qIsNaN(v))
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_EXPOSURETIME), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_FLASH)).isEmpty()) {
|
||||||
|
auto v = flash();
|
||||||
|
if (v != Flash::NotSet)
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_FLASH), QStringLiteral("%1").arg(quint16(v)));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_FNUMBER)).isEmpty()) {
|
||||||
|
auto v = fNumber();
|
||||||
|
if (!qIsNaN(v))
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_FNUMBER), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_FOCALLENGTH)).isEmpty()) {
|
||||||
|
auto v = focalLength();
|
||||||
|
if (!qIsNaN(v))
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_FOCALLENGTH), QStringLiteral("%1").arg(v, 0, 'g', 9));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_ISOSPEEDRATINGS)).isEmpty()) {
|
||||||
|
auto v = isoSpeedRatings();
|
||||||
|
if (v != 0)
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_ISOSPEEDRATINGS), QStringLiteral("%1").arg(v));
|
||||||
|
}
|
||||||
|
if (replaceExisting || targetImage.text(QStringLiteral(META_KEY_WHITEBALANCE)).isEmpty()) {
|
||||||
|
auto v = whiteBalance();
|
||||||
|
if (v != WhiteBalance::NotSet)
|
||||||
|
targetImage.setText(QStringLiteral(META_KEY_WHITEBALANCE), QStringLiteral("%1").arg(quint16(v)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MicroExif::updateImageResolution(QImage &targetImage)
|
bool MicroExif::updateImageResolution(QImage &targetImage)
|
||||||
@@ -1217,7 +1447,7 @@ MicroExif MicroExif::fromByteArray(const QByteArray &ba, bool searchHeader)
|
|||||||
idx = std::min(idxLE, idxBE);
|
idx = std::min(idxLE, idxBE);
|
||||||
else
|
else
|
||||||
idx = idxLE > -1 ? idxLE : idxBE;
|
idx = idxLE > -1 ? idxLE : idxBE;
|
||||||
if(idx > 0)
|
if (idx > 0)
|
||||||
ba0 = ba0.mid(idx);
|
ba0 = ba0.mid(idx);
|
||||||
}
|
}
|
||||||
QBuffer buf;
|
QBuffer buf;
|
||||||
@@ -1308,7 +1538,7 @@ MicroExif MicroExif::fromImage(const QImage &image)
|
|||||||
dt = QDateTime::currentDateTime();
|
dt = QDateTime::currentDateTime();
|
||||||
exif.setDateTimeOriginal(dt);
|
exif.setDateTimeOriginal(dt);
|
||||||
|
|
||||||
// GPS Info
|
// GPS info
|
||||||
auto ok = false;
|
auto ok = false;
|
||||||
auto alt = image.text(QStringLiteral(META_KEY_ALTITUDE)).toDouble(&ok);
|
auto alt = image.text(QStringLiteral(META_KEY_ALTITUDE)).toDouble(&ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
@@ -1322,6 +1552,38 @@ MicroExif MicroExif::fromImage(const QImage &image)
|
|||||||
auto dir = image.text(QStringLiteral(META_KEY_DIRECTION)).toDouble(&ok);
|
auto dir = image.text(QStringLiteral(META_KEY_DIRECTION)).toDouble(&ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
exif.setImageDirection(dir);
|
exif.setImageDirection(dir);
|
||||||
|
auto spd = image.text(QStringLiteral(META_KEY_SPEED)).toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setImageSpeed(spd);
|
||||||
|
|
||||||
|
// EXIF shot info
|
||||||
|
auto zoom = image.text(QStringLiteral(META_KEY_DIGITALZOOMRATIO)).toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setDigitalZoomRatio(zoom);
|
||||||
|
auto expm = image.text(QStringLiteral(META_KEY_EXPOSUREMODE)).toUShort(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setExposureMode(ExposureMode(expm));
|
||||||
|
auto expp = image.text(QStringLiteral(META_KEY_EXPOSUREPROGRAM)).toUShort(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setExposureProgram(ExposureProgram(expp));
|
||||||
|
auto expt = image.text(QStringLiteral(META_KEY_EXPOSURETIME)).toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setExposureTime(expt);
|
||||||
|
auto flsh = image.text(QStringLiteral(META_KEY_FLASH)).toUShort(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setFlash(FlashFlags(flsh));
|
||||||
|
auto fnum = image.text(QStringLiteral(META_KEY_FNUMBER)).toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setFNumber(fnum);
|
||||||
|
auto flen = image.text(QStringLiteral(META_KEY_FOCALLENGTH)).toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setFocalLength(flen);
|
||||||
|
auto isos = image.text(QStringLiteral(META_KEY_ISOSPEEDRATINGS)).toUShort(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setIsoSpeedRatings(isos);
|
||||||
|
auto whtb = image.text(QStringLiteral(META_KEY_WHITEBALANCE)).toUShort(&ok);
|
||||||
|
if (ok)
|
||||||
|
exif.setWhiteBalance(WhiteBalance(whtb));
|
||||||
|
|
||||||
return exif;
|
return exif;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,85 @@
|
|||||||
#define EXIF_DEFAULT_BYTEORDER QDataStream::BigEndian
|
#define EXIF_DEFAULT_BYTEORDER QDataStream::BigEndian
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The Flash enum
|
||||||
|
*/
|
||||||
|
enum class Flash : quint16 {
|
||||||
|
NotSet = 0,
|
||||||
|
|
||||||
|
// Values for bit 0 indicating whether the flash fired.
|
||||||
|
// 0b = Flash did not fire.
|
||||||
|
// 1b = Flash fired.
|
||||||
|
Fired = 1,
|
||||||
|
|
||||||
|
// Values for bits 1 and 2 indicating the status of returned light.
|
||||||
|
// 00b = No strobe return detection function
|
||||||
|
// 01b = reserved
|
||||||
|
// 10b = Strobe return light not detected.
|
||||||
|
// 11b = Strobe return light detected.
|
||||||
|
ReturnLightNotDetected = 2 << 1,
|
||||||
|
ReturnLightDetected = 3 << 1,
|
||||||
|
|
||||||
|
// Values for bits 3 and 4 indicating the camera's flash mode.
|
||||||
|
// 00b = unknown
|
||||||
|
// 01b = Compulsory flash firing
|
||||||
|
// 10b = Compulsory flash suppression
|
||||||
|
// 11b = Auto mode
|
||||||
|
CompulsoryFiring = 1 << 3,
|
||||||
|
CompulsorySuppression = 2 << 3,
|
||||||
|
AutoMode = 3 << 3,
|
||||||
|
|
||||||
|
// Values for bit 5 indicating the presence of a flash function.
|
||||||
|
// 0b = Flash function present
|
||||||
|
// 1b = No flash function
|
||||||
|
FlashNotAvailable = 1 << 5,
|
||||||
|
|
||||||
|
// Values for bit 6 indicating the camera's red-eye mode.
|
||||||
|
// 0b = No red-eye reduction mode or unknown
|
||||||
|
// 1b = Red-eye reduction supported
|
||||||
|
RedEyeReductionSupported = 1 << 6,
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(FlashFlags, Flash)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(FlashFlags)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The ExposureMode enum
|
||||||
|
*/
|
||||||
|
enum class ExposureMode : quint16 {
|
||||||
|
Auto,
|
||||||
|
Manual,
|
||||||
|
AutoBracket,
|
||||||
|
|
||||||
|
NotSet = 65535
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The ExposureProgram enum
|
||||||
|
*/
|
||||||
|
enum class ExposureProgram : quint16 {
|
||||||
|
NotDefined,
|
||||||
|
Manual,
|
||||||
|
Normal,
|
||||||
|
AperturePriority,
|
||||||
|
ShutterPriority,
|
||||||
|
Creative,
|
||||||
|
Action,
|
||||||
|
PortraitMode,
|
||||||
|
LandscapeMode,
|
||||||
|
|
||||||
|
NotSet = 65535
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The WhiteBalance enum
|
||||||
|
*/
|
||||||
|
enum class WhiteBalance : quint16 {
|
||||||
|
Auto,
|
||||||
|
Manual,
|
||||||
|
|
||||||
|
NotSet = 65535
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The MicroExif class
|
* \brief The MicroExif class
|
||||||
* Class to extract / write minimal EXIF data (e.g. resolution, rotation,
|
* Class to extract / write minimal EXIF data (e.g. resolution, rotation,
|
||||||
@@ -236,6 +315,69 @@ public:
|
|||||||
QUuid uniqueId() const;
|
QUuid uniqueId() const;
|
||||||
void setUniqueId(const QUuid &uuid);
|
void setUniqueId(const QUuid &uuid);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief digitalZoomRatio
|
||||||
|
* \return The digital zoom ratio when the image was shot or NaN if not set.
|
||||||
|
*/
|
||||||
|
double digitalZoomRatio() const;
|
||||||
|
void setDigitalZoomRatio(double zoom);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief exposureMode
|
||||||
|
* \return The exposure mode set when the image was shot. In auto-bracketing mode, the camera shoots a series of frames of the same scene at different exposure settings.
|
||||||
|
*/
|
||||||
|
ExposureMode exposureMode() const;
|
||||||
|
void setExposureMode(const ExposureMode& em);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief exposureProgram
|
||||||
|
* \return The class of the program used by the camera to set exposure when the picture is taken.
|
||||||
|
*/
|
||||||
|
ExposureProgram exposureProgram() const;
|
||||||
|
void setExposureProgram(const ExposureProgram& ep);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief exposureTime
|
||||||
|
* \return Exposure time, given in seconds (sec) or NaN if not set.
|
||||||
|
*/
|
||||||
|
double exposureTime() const;
|
||||||
|
void setExposureTime(double et);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief fNumber
|
||||||
|
* \return The F number or NaN if not set.
|
||||||
|
*/
|
||||||
|
double fNumber() const;
|
||||||
|
void setFNumber(double f);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief focalLength
|
||||||
|
* \return The actual focal length of the lens, in mm.
|
||||||
|
*/
|
||||||
|
double focalLength() const;
|
||||||
|
void setFocalLength(double fl);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief flash
|
||||||
|
* \return The status of flash when the image was shot.
|
||||||
|
*/
|
||||||
|
FlashFlags flash() const;
|
||||||
|
void setFlash(const FlashFlags& flash);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief isoSpeedRatings
|
||||||
|
* \return The sensitivity of the camera or input device when the image was shot.
|
||||||
|
*/
|
||||||
|
quint16 isoSpeedRatings() const;
|
||||||
|
void setIsoSpeedRatings(quint16 iso);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief whiteBalance
|
||||||
|
* \return The white balance mode set when the image was shot.
|
||||||
|
*/
|
||||||
|
WhiteBalance whiteBalance() const;
|
||||||
|
void setWhiteBalance(const WhiteBalance& wb);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief latitude
|
* \brief latitude
|
||||||
* \return Floating-point number indicating the latitude in degrees north of the equator (e.g. 27.717) or NaN if not set.
|
* \return Floating-point number indicating the latitude in degrees north of the equator (e.g. 27.717) or NaN if not set.
|
||||||
@@ -258,6 +400,13 @@ public:
|
|||||||
double altitude() const;
|
double altitude() const;
|
||||||
void setAltitude(double meters);
|
void setAltitude(double meters);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief imageSpeed
|
||||||
|
* \return The speed in Km/h or NaN if not set.
|
||||||
|
*/
|
||||||
|
double imageSpeed() const;
|
||||||
|
void setImageSpeed(double kmh);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief imageDirection
|
* \brief imageDirection
|
||||||
* \param isMagnetic Set to true if the direction is relative to magnetic north, false if it is relative to true north. Leave nullptr if is not of interest.
|
* \param isMagnetic Set to true if the direction is relative to magnetic north, false if it is relative to true north. Leave nullptr if is not of interest.
|
||||||
|
|||||||
@@ -34,10 +34,22 @@
|
|||||||
#define META_KEY_MODIFICATIONDATE "ModificationDate"
|
#define META_KEY_MODIFICATIONDATE "ModificationDate"
|
||||||
#define META_KEY_OWNER "Owner"
|
#define META_KEY_OWNER "Owner"
|
||||||
#define META_KEY_SOFTWARE "Software"
|
#define META_KEY_SOFTWARE "Software"
|
||||||
|
#define META_KEY_SPEED "Speed"
|
||||||
#define META_KEY_TITLE "Title"
|
#define META_KEY_TITLE "Title"
|
||||||
#define META_KEY_XML_GIMP "XML:org.gimp.xml"
|
#define META_KEY_XML_GIMP "XML:org.gimp.xml"
|
||||||
#define META_KEY_XMP_ADOBE "XML:com.adobe.xmp"
|
#define META_KEY_XMP_ADOBE "XML:com.adobe.xmp"
|
||||||
|
|
||||||
|
// Shot info metadata keys
|
||||||
|
#define META_KEY_DIGITALZOOMRATIO "DigitalZoomRatio"
|
||||||
|
#define META_KEY_EXPOSUREMODE "ExposureMode"
|
||||||
|
#define META_KEY_EXPOSUREPROGRAM "ExposureProgram"
|
||||||
|
#define META_KEY_EXPOSURETIME "ExposureTime"
|
||||||
|
#define META_KEY_FLASH "Flash"
|
||||||
|
#define META_KEY_FNUMBER "FNumber"
|
||||||
|
#define META_KEY_FOCALLENGTH "FocalLength"
|
||||||
|
#define META_KEY_ISOSPEEDRATINGS "ISOSpeedRatings"
|
||||||
|
#define META_KEY_WHITEBALANCE "WhiteBalance"
|
||||||
|
|
||||||
// Camera info metadata keys
|
// Camera info metadata keys
|
||||||
#define META_KEY_MANUFACTURER "Manufacturer"
|
#define META_KEY_MANUFACTURER "Manufacturer"
|
||||||
#define META_KEY_MODEL "Model"
|
#define META_KEY_MODEL "Model"
|
||||||
|
|||||||
Reference in New Issue
Block a user