git repos / SagoImageBrowser

blame: src/exifreader.cpp

normal view · raw

53fdab93 Poul Sander 2026-05-18 18:45 1
#include "exifreader.h"
53fdab93 Poul Sander 2026-05-18 18:45 2
53fdab93 Poul Sander 2026-05-18 18:45 3
#include <QFileInfo>
53fdab93 Poul Sander 2026-05-18 18:45 4
#include <QImageReader>
53fdab93 Poul Sander 2026-05-18 18:45 5
53fdab93 Poul Sander 2026-05-18 18:45 6
#include <exiv2/exiv2.hpp>
53fdab93 Poul Sander 2026-05-18 18:45 7
53fdab93 Poul Sander 2026-05-18 18:45 8
bool ExifData::isEmpty() const
53fdab93 Poul Sander 2026-05-18 18:45 9
{
53fdab93 Poul Sander 2026-05-18 18:45 10
    return dateTime.isEmpty() && make.isEmpty() && model.isEmpty()
53fdab93 Poul Sander 2026-05-18 18:45 11
        && exposureTime.isEmpty() && fNumber.isEmpty() && iso.isEmpty()
53fdab93 Poul Sander 2026-05-18 18:45 12
        && focalLength.isEmpty() && flash.isEmpty()
53fdab93 Poul Sander 2026-05-18 18:45 13
        && dimensions.isEmpty() && fileSize.isEmpty();
53fdab93 Poul Sander 2026-05-18 18:45 14
}
53fdab93 Poul Sander 2026-05-18 18:45 15
53fdab93 Poul Sander 2026-05-18 18:45 16
QList<QPair<QString, QString>> ExifData::toList() const
53fdab93 Poul Sander 2026-05-18 18:45 17
{
53fdab93 Poul Sander 2026-05-18 18:45 18
    QList<QPair<QString, QString>> result;
53fdab93 Poul Sander 2026-05-18 18:45 19
    auto add = [&](const char *label, const QString &value) {
53fdab93 Poul Sander 2026-05-18 18:45 20
        if (!value.isEmpty())
53fdab93 Poul Sander 2026-05-18 18:45 21
            result.append({QString::fromLatin1(label), value});
53fdab93 Poul Sander 2026-05-18 18:45 22
    };
53fdab93 Poul Sander 2026-05-18 18:45 23
    add("Date/Time",    dateTime);
53fdab93 Poul Sander 2026-05-18 18:45 24
    add("Camera Make",  make);
53fdab93 Poul Sander 2026-05-18 18:45 25
    add("Camera Model", model);
53fdab93 Poul Sander 2026-05-18 18:45 26
    add("Exposure",     exposureTime);
53fdab93 Poul Sander 2026-05-18 18:45 27
    add("Aperture",     fNumber);
53fdab93 Poul Sander 2026-05-18 18:45 28
    add("ISO",          iso);
53fdab93 Poul Sander 2026-05-18 18:45 29
    add("Focal Length", focalLength);
53fdab93 Poul Sander 2026-05-18 18:45 30
    add("Flash",        flash);
53fdab93 Poul Sander 2026-05-18 18:45 31
    add("Dimensions",   dimensions);
53fdab93 Poul Sander 2026-05-18 18:45 32
    add("File Size",    fileSize);
53fdab93 Poul Sander 2026-05-18 18:45 33
    return result;
53fdab93 Poul Sander 2026-05-18 18:45 34
}
53fdab93 Poul Sander 2026-05-18 18:45 35
53fdab93 Poul Sander 2026-05-18 18:45 36
ExifData ExifReader::read(const QString &path)
53fdab93 Poul Sander 2026-05-18 18:45 37
{
53fdab93 Poul Sander 2026-05-18 18:45 38
    ExifData data;
53fdab93 Poul Sander 2026-05-18 18:45 39
53fdab93 Poul Sander 2026-05-18 18:45 40
    QFileInfo fi(path);
53fdab93 Poul Sander 2026-05-18 18:45 41
    if (!fi.exists() || fi.isDir())
53fdab93 Poul Sander 2026-05-18 18:45 42
        return data;
53fdab93 Poul Sander 2026-05-18 18:45 43
53fdab93 Poul Sander 2026-05-18 18:45 44
    // File size
53fdab93 Poul Sander 2026-05-18 18:45 45
    {
53fdab93 Poul Sander 2026-05-18 18:45 46
        qint64 size = fi.size();
53fdab93 Poul Sander 2026-05-18 18:45 47
        if (size < 1024)
53fdab93 Poul Sander 2026-05-18 18:45 48
            data.fileSize = QString::number(size) + QLatin1String(" B");
53fdab93 Poul Sander 2026-05-18 18:45 49
        else if (size < 1024 * 1024)
53fdab93 Poul Sander 2026-05-18 18:45 50
            data.fileSize = QString::number(size / 1024.0, 'f', 1) + QLatin1String(" KiB");
53fdab93 Poul Sander 2026-05-18 18:45 51
        else
53fdab93 Poul Sander 2026-05-18 18:45 52
            data.fileSize = QString::number(size / (1024.0 * 1024.0), 'f', 1) + QLatin1String(" MiB");
53fdab93 Poul Sander 2026-05-18 18:45 53
    }
53fdab93 Poul Sander 2026-05-18 18:45 54
53fdab93 Poul Sander 2026-05-18 18:45 55
    // Image dimensions via Qt (reads only the header, no full decode needed)
53fdab93 Poul Sander 2026-05-18 18:45 56
    {
53fdab93 Poul Sander 2026-05-18 18:45 57
        QImageReader reader(path);
53fdab93 Poul Sander 2026-05-18 18:45 58
        reader.setDecideFormatFromContent(true);
53fdab93 Poul Sander 2026-05-18 18:45 59
        QSize sz = reader.size();
53fdab93 Poul Sander 2026-05-18 18:45 60
        if (sz.isValid())
53fdab93 Poul Sander 2026-05-18 18:45 61
            data.dimensions = QString::fromLatin1("%1 * %2")
53fdab93 Poul Sander 2026-05-18 18:45 62
                                  .arg(sz.width()).arg(sz.height());
53fdab93 Poul Sander 2026-05-18 18:45 63
    }
53fdab93 Poul Sander 2026-05-18 18:45 64
53fdab93 Poul Sander 2026-05-18 18:45 65
    // EXIF tags via exiv2
53fdab93 Poul Sander 2026-05-18 18:45 66
    try {
53fdab93 Poul Sander 2026-05-18 18:45 67
        auto image = Exiv2::ImageFactory::open(path.toStdString());
53fdab93 Poul Sander 2026-05-18 18:45 68
        image->readMetadata();
53fdab93 Poul Sander 2026-05-18 18:45 69
        const Exiv2::ExifData &exif = image->exifData();
53fdab93 Poul Sander 2026-05-18 18:45 70
53fdab93 Poul Sander 2026-05-18 18:45 71
        auto findTag = [&](const std::string &key) -> QString {
53fdab93 Poul Sander 2026-05-18 18:45 72
            try {
53fdab93 Poul Sander 2026-05-18 18:45 73
                auto it = exif.findKey(Exiv2::ExifKey(key));
53fdab93 Poul Sander 2026-05-18 18:45 74
                if (it != exif.end())
53fdab93 Poul Sander 2026-05-18 18:45 75
                    return QString::fromStdString(it->print(&exif)).trimmed();
53fdab93 Poul Sander 2026-05-18 18:45 76
            } catch (...) {}
53fdab93 Poul Sander 2026-05-18 18:45 77
            return {};
53fdab93 Poul Sander 2026-05-18 18:45 78
        };
53fdab93 Poul Sander 2026-05-18 18:45 79
53fdab93 Poul Sander 2026-05-18 18:45 80
        data.dateTime = findTag("Exif.Photo.DateTimeOriginal");
53fdab93 Poul Sander 2026-05-18 18:45 81
        if (data.dateTime.isEmpty())
53fdab93 Poul Sander 2026-05-18 18:45 82
            data.dateTime = findTag("Exif.Image.DateTime");
53fdab93 Poul Sander 2026-05-18 18:45 83
        data.make         = findTag("Exif.Image.Make");
53fdab93 Poul Sander 2026-05-18 18:45 84
        data.model        = findTag("Exif.Image.Model");
53fdab93 Poul Sander 2026-05-18 18:45 85
        data.exposureTime = findTag("Exif.Photo.ExposureTime");
53fdab93 Poul Sander 2026-05-18 18:45 86
        data.fNumber      = findTag("Exif.Photo.FNumber");
53fdab93 Poul Sander 2026-05-18 18:45 87
        data.iso          = findTag("Exif.Photo.ISOSpeedRatings");
53fdab93 Poul Sander 2026-05-18 18:45 88
        data.focalLength  = findTag("Exif.Photo.FocalLength");
53fdab93 Poul Sander 2026-05-18 18:45 89
        data.flash        = findTag("Exif.Photo.Flash");
53fdab93 Poul Sander 2026-05-18 18:45 90
    } catch (const Exiv2::Error &) {
53fdab93 Poul Sander 2026-05-18 18:45 91
        // No EXIF or unsupported format — leave tags empty
53fdab93 Poul Sander 2026-05-18 18:45 92
    }
53fdab93 Poul Sander 2026-05-18 18:45 93
53fdab93 Poul Sander 2026-05-18 18:45 94
    return data;
53fdab93 Poul Sander 2026-05-18 18:45 95
}
1970-01-01 00:00 96