Bug 151275 - camera tool: date & time should be taken from exif not file modified date
Summary: camera tool: date & time should be taken from exif not file modified date
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Import-PostProcessing (show other bugs)
Version: 0.9.2
Platform: Ubuntu Linux
: NOR normal
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-24 04:45 UTC by Guy
Modified: 2017-08-16 05:55 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 0.10.0


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Guy 2007-10-24 04:45:44 UTC
Version:           0.9.2 (using KDE KDE 3.5.8)
Installed from:    Ubuntu Packages
OS:                Linux

Not sure if it is a bug or wishlist, but with the current trend of digital cameras it is more of a bug then a wishlist. So here it goes. When adding new photos with an camera tool the date/time should be taken from exif information not file modified time. Many times the files will be shuffled around the system and modified by external programs that makes file modified time useless for the purpose of establishing created time. However, for the sake of those that have images with incorrect/missing exif date/time there can be a check box right before Add Camera Name option.
Comment 1 Arnd Baecker 2007-10-24 07:41:16 UTC
To me this sounds very much like a duplicate of
http://bugs.kde.org/show_bug.cgi?id=141014
I would suggest that you add anything additional there and mark
this one as duplicate of bug 141014.
Comment 2 Guy 2007-10-24 10:08:37 UTC
All hope is not lost, there is a way around the problem. just run this code before importing photos 'jhead -ft *.JPG' that will reset file modified time to exif date/time.

The bug 141014 is general. I am suggesting to add a check box in import tool to select what should be used as time (exif or mtime)

If you guys think that an application wide setting is more useful then we can mark this as duplicate and move our discussion there.
Comment 3 caulier.gilles 2008-12-17 12:00:31 UTC
SVN commit 897995 by cgilles:

digiKam from KDE3 branch : Camera GUI improvements: USB mass Storage camera: items date management:
- Use metadata from THM files if available to get item informations.
- Video files date are extracted from THM if possible. In this case video files are sorted by date properlly.
- If THM files are not available, we trying to extract date from orginal file metadata.
- If metadata are not available, we use file creation time stamp instead file Modification time stamp.


 M  +103 -60   umscamera.cpp
 M  +8 -8      umscamera.h


--- branches/extragear/kde3/graphics/digikam/utilities/cameragui/umscamera.cpp #897994:897995
@@ -7,7 +7,7 @@
 * Description : USB Mass Storage camera interface
 *
 * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
- * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
@@ -101,8 +101,10 @@
    if (!list)
        return false;

-    QFileInfoListIterator it( *list );
+    QFileInfoListIterator it(*list);
    QFileInfo *fi;
+    QFileInfo thmlo, thmup;
+    DMetadata meta;

    while ((fi = it.current()) != 0 && !m_cancel)
    {
@@ -112,38 +114,68 @@

        if (!mime.isEmpty())
        {
+            QSize      dims;
+            QDateTime  dt;
            GPItemInfo info;
-            QSize dims(-1, -1);
+            thmlo.setFile(folder + QString("/") + fi->baseName() + QString(".thm"));
+            thmup.setFile(folder + QString("/") + fi->baseName() + QString(".THM"));

-            if (getImageDimensions)
+            if (thmlo.exists())
            {
-                if (mime == QString("image/x-raw"))
+                // Try thumbnail sidecar files with lowercase extension.
+                meta.load(thmlo.filePath());
+                dt   = meta.getImageDateTime();
+                dims = meta.getImageDimensions();
+            }
+            else if (thmup.exists())
+            {
+                // Try thumbnail sidecar files with uppercase extension.
+                meta.load(thmup.filePath());
+                dt   = meta.getImageDateTime();
+                dims = meta.getImageDimensions();
+            }
+            else if (mime == QString("image/x-raw"))
+            {
+                // If no thumbnail sidecar file available , try to load image metadata with Raw files.
+                meta.load(fi->filePath());
+                dt   = meta.getImageDateTime();
+                dims = meta.getImageDimensions();
+            }
+            else
+            {
+                meta.load(fi->filePath());
+                dt   = meta.getImageDateTime();
+                dims = meta.getImageDimensions();
+
+                if (dims.isNull())
                {
-                    DMetadata metaData(fi->filePath());
-                    dims = metaData.getImageDimensions();
-                }
-                else
-                {
-                    KFileMetaInfo meta(fi->filePath());
-                    if (meta.isValid())
+                    // In all others case, try KFileMetaInfo.
+                    KFileMetaInfo kmeta(fi->filePath());
+                    if (kmeta.isValid())
                    {
-                        if (meta.containsGroup("Jpeg EXIF Data"))
-                            dims = meta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
-                        else if (meta.containsGroup("General"))
-                            dims = meta.group("General").item("Dimensions").value().toSize();
-                        else if (meta.containsGroup("Technical"))
-                            dims = meta.group("Technical").item("Dimensions").value().toSize();
+                        if (kmeta.containsGroup("Jpeg EXIF Data"))
+                            dims = kmeta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
+                        else if (kmeta.containsGroup("General"))
+                            dims = kmeta.group("General").item("Dimensions").value().toSize();
+                        else if (kmeta.containsGroup("Technical"))
+                            dims = kmeta.group("Technical").item("Dimensions").value().toSize();
                    }
                }
            }

+            if (dt.isNull())
+            {
+                // If date is not found in metadata, use file time stamp
+                dt = fi->created();
+            }
+
            info.name             = fi->fileName();
            info.folder           = !folder.endsWith("/") ? folder + QString("/") : folder;
            info.mime             = mime;
-            info.mtime            = fi->lastModified().toTime_t();
+            info.mtime            = dt.toTime_t();
            info.size             = fi->size();
-            info.width            = dims.width();
-            info.height           = dims.height();
+            info.width            = getImageDimensions ? dims.width()  : -1;
+            info.height           = getImageDimensions ? dims.height() : -1;
            info.downloaded       = GPItemInfo::DownloadUnknow;
            info.readPermissions  = fi->isReadable();
            info.writePermissions = fi->isWritable();
@@ -173,10 +205,9 @@
        return true;

    // THM files: try to get thumbnail from '.thm' files if we didn't manage to get
-    // thumbnail from Exif. Any cameras provides *.thm files like JPEG files with RAW files.
-    // Using this way is always speed up than ultimate loading using DImg.
-    // Nota: the thumbnail extracted with this method can be in poor quality.
-    // 2006/27/01 - Gilles - Tested with my Minolta Dynax 5D USM camera.
+    // thumbnail from Exif. Any cameras provides *.thm files like JPEG files with RAW/video files.
+    // Using this way speed up thumbnailization and limit data transfered between camera and computer.
+    // NOTE: the thumbnail extracted with this method can provide a poor quality preview.

    QFileInfo fi(folder + QString("/") + itemName);

@@ -191,7 +222,6 @@
           return true;
    }

-
    // Finaly, we trying to get thumbnail using DImg API (slow).

    DImg dimgThumb(QFile::encodeName(folder + QString("/") + itemName));
@@ -215,8 +245,7 @@

 bool UMSCamera::downloadItem(const QString& folder, const QString& itemName, const QString& saveFile)
 {
-    m_cancel = false;
-
+    m_cancel     = false;
    QString src  = folder + QString("/") + itemName;
    QString dest = saveFile;

@@ -226,7 +255,7 @@
    if ( !sFile.open(IO_ReadOnly) )
    {
        DWarning() << "Failed to open source file for reading: "
-                    << src << endl;
+                   << src << endl;
        return false;
    }

@@ -271,7 +300,7 @@

 bool UMSCamera::setLockItem(const QString& folder, const QString& itemName, bool lock)
 {
-    QString src  = folder + QString("/") + itemName;
+    QString src = folder + QString("/") + itemName;

    if (lock)
    {
@@ -312,10 +341,9 @@
 }

 bool UMSCamera::uploadItem(const QString& folder, const QString& itemName, const QString& localFile,
-                           GPItemInfo& itemInfo, bool getImageDimensions)
+                           GPItemInfo& info, bool getImageDimensions)
 {
-    m_cancel = false;
-
+    m_cancel     = false;
    QString dest = folder + QString("/") + itemName;
    QString src  = localFile;

@@ -367,45 +395,60 @@

    // Get new camera item information.

+    DMetadata meta;
    QFileInfo fi(dest);
-    QString mime = mimeType(fi.extension(false).lower());
+    QString   mime = mimeType(fi.extension(false).lower());

    if (!mime.isEmpty())
    {
-        QSize dims(-1, -1);
+        QSize     dims;
+        QDateTime dt;

-        if (getImageDimensions)
+        if (mime == QString("image/x-raw"))
        {
-            if (mime == QString("image/x-raw"))
+            // Try to load image metadata with Raw files.
+            meta.load(fi.filePath());
+            dt   = meta.getImageDateTime();
+            dims = meta.getImageDimensions();
+        }
+        else
+        {
+            meta.load(fi.filePath());
+            dt   = meta.getImageDateTime();
+            dims = meta.getImageDimensions();
+
+            if (dims.isNull())
            {
-                DMetadata metaData(fi.filePath());
-                dims = metaData.getImageDimensions();
-            }
-            else
-            {
-                KFileMetaInfo meta(fi.filePath());
-                if (meta.isValid())
+                // In all others case, try KFileMetaInfo.
+                KFileMetaInfo kmeta(fi.filePath());
+                if (kmeta.isValid())
                {
-                    if (meta.containsGroup("Jpeg EXIF Data"))
-                        dims = meta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
-                    else if (meta.containsGroup("General"))
-                        dims = meta.group("General").item("Dimensions").value().toSize();
-                    else if (meta.containsGroup("Technical"))
-                        dims = meta.group("Technical").item("Dimensions").value().toSize();
+                    if (kmeta.containsGroup("Jpeg EXIF Data"))
+                        dims = kmeta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
+                    else if (kmeta.containsGroup("General"))
+                        dims = kmeta.group("General").item("Dimensions").value().toSize();
+                    else if (kmeta.containsGroup("Technical"))
+                        dims = kmeta.group("Technical").item("Dimensions").value().toSize();
                }
            }
        }

-        itemInfo.name             = fi.fileName();
-        itemInfo.folder           = !folder.endsWith("/") ? folder + QString("/") : folder;
-        itemInfo.mime             = mime;
-        itemInfo.mtime            = fi.lastModified().toTime_t();
-        itemInfo.size             = fi.size();
-        itemInfo.width            = dims.width();
-        itemInfo.height           = dims.height();
-        itemInfo.downloaded       = GPItemInfo::DownloadUnknow;
-        itemInfo.readPermissions  = fi.isReadable();
-        itemInfo.writePermissions = fi.isWritable();
+        if (dt.isNull())
+        {
+            // If date is not found in metadata, use file time stamp
+            dt = fi.created();
+        }
+
+        info.name             = fi.fileName();
+        info.folder           = !folder.endsWith("/") ? folder + QString("/") : folder;
+        info.mime             = mime;
+        info.mtime            = dt.toTime_t();
+        info.size             = fi.size();
+        info.width            = getImageDimensions ? dims.width()  : -1;
+        info.height           = getImageDimensions ? dims.height() : -1;
+        info.downloaded       = GPItemInfo::DownloadUnknow;
+        info.readPermissions  = fi.isReadable();
+        info.writePermissions = fi.isWritable();
    }

    return true;
--- branches/extragear/kde3/graphics/digikam/utilities/cameragui/umscamera.h #897994:897995
@@ -5,21 +5,21 @@
 *
 * Date        : 2004-12-21
 * Description : USB Mass Storage camera interface
- *
+ *
 * Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
- * Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ * Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * This program is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software Foundation;
 * either version 2, or (at your option)
 * any later version.
- *
+ *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
- *
+ *
 * ============================================================ */

 #ifndef UMSCAMERA_H
@@ -49,7 +49,7 @@
    void cancel();

    void getAllFolders(const QString& folder, QStringList& subFolderList);
-    bool getItemsInfoList(const QString& folder, GPItemInfoList& infoList, bool getImageDimensions = true);
+    bool getItemsInfoList(const QString& folder, GPItemInfoList& infoList, bool getImageDimensions=true);
    bool getThumbnail(const QString& folder, const QString& itemName, QImage& thumbnail);
    bool getExif(const QString& folder, const QString& itemName, char **edata, int& esize);

@@ -57,8 +57,8 @@

    bool downloadItem(const QString& folder, const QString& itemName, const QString& saveFile);
    bool deleteItem(const QString& folder, const QString& itemName);
-    bool uploadItem(const QString& folder, const QString& itemName, const QString& localFile,
-                    GPItemInfo& itemInfo, bool getImageDimensions=true);
+    bool uploadItem(const QString& folder, const QString& itemName, const QString& localFile,
+                    GPItemInfo& info, bool getImageDimensions=true);

    bool cameraSummary(QString& summary);
    bool cameraManual(QString& manual);
@@ -68,7 +68,7 @@

    void listFolders(const QString& folder, QStringList& subFolderList);

-private :
+private:

    bool m_cancel;
 };
Comment 4 caulier.gilles 2008-12-17 15:14:09 UTC
SVN commit 898140 by cgilles:

backport commit #897995 from KDE3 branch
BUG: 177242
BUG: 151275
BUG: 146764
CCBUG: 136897


 M  +1 -2      cameracontroller.cpp  
 M  +1 -2      gpcamera.cpp  
 M  +60 -84    umscamera.cpp  
 M  +4 -4      umscamera.h  


WebSVN link: http://websvn.kde.org/?view=rev&revision=898140