Autor |
Beitrag |
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: Mo 29.04.19 20:49
Hallo zusammen,
benötige etwas Hilfe im Sprachenwirrwarr Datum - Änderungsdatum - Aufnahmedatum - Erstelldatum. Diese vier Begriffe zeigt der MS-Explorer in unterschiedlichen Situationen unter Details.
Wie an anderer Stelle erwähnt, erstelle ich ein eigenes kl. Programm zum Ändern des Dateidatums. Dieses Programm funktioniert wunschgemäß, bis ich plötzlich Abweichungen in der Anzeige gegenüber dem MS-Explorer erkannte. Stelle unter WIN10 folgende Eigenschaft fest (die verwirrt):
Ändere ich das Dateidatum mit der Funktion
FileSetDate(FileHandle,dt.Time )
so funktioniert dies bei allen nicht-grafik-Dateitypen, wie pas, txt, aber auch bei einigen Grafik-typen wie bmp, ico. Genauer gesagt: das neue Datum stimmt mit der Anzeige im MS-Explorer überein. Dort erscheint als Überschrift "Änderungsdatum".
Bei Verzeichnissen die nur jpg-Dateien enthalten, wechselt die Überschrift im Explorer auf "Datum" und unter Details wird erkennbar, dass vorrangig - sofern vorhanden -das Aufnahmedatum und nicht das Änderungsdatum angezeigt wird. Dies führt logischer weise zu abweichenden Anzeigen (siehe Anlage).
Wünschte ich gleiche Anzeige zwischen meinem (Pascal-)Programmen und dem MS-Explorer, müsste ich nicht nur das Filedatum (Änderungsdatum), sondern auch das Aufnahmedatum ident ändern. Daneben gibt es als Drittes noch das "Erstelldatum".
1. Ist bekannt warum MS bei Bildern das Aufnahemedatum nicht das Pascal-Filedatum anzeigt?
2. Wer kann sprachlich aufklären? Ist Aufnahmedatum = Exif-Datum und was ist dann das Erstelldatum?
3. Mit welcher Pascal-Funktion kann ich bei Bildern das "Aufnahmedatum" ändern? In TSearchRec kann ich keinen Ansatz finden.
4. Gibt es ggf. eine Pascal-Funktion die beides in einem Schritt ändert - ohne Fehler zu liefern wenn die zu ändernde Datei keine Bilddatei ist?
Wäre dankbar für mehr Klarheit und Lösungsvorschläge. hRb
Einloggen, um Attachments anzusehen!
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 29.04.19 22:57
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Holgerx
Beiträge: 63
Erhaltene Danke: 27
Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
|
Verfasst: Di 30.04.19 05:30
Hmm..
Dir ist bewusst, das Erstelldatum / Änderungsdatum eine Fileinformation im Dateissystem ist, jedoch Aufnahmedatum eine 'zusätzliche' Information aus der Datei selber?
Der Explorer holt z.B. bei Ordnern mit reinen Bild Dateien eben aus diesen die eingebetteten zusätzlichen Informationen, wie z.B: Aufnahmedatum oder Auflösung.
Er 'meint' intelligent zu sein, auch wenn der Benutzer eigentlich das Filedatum haben möchte.
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: Di 30.04.19 22:47
Hallo Frühlingsrolle, Holgerx
zunächst danke für die Antworten. Habe vermutlich zu viele Fragen auf einmal gestellt - auch mit falschen Annahmen. Zur Aufklärung:
1. Das Wort "Pascal-Filedatum" habe ich gewählt, weil ich von der Hilfe nur das Filedatum aus TSearchRec.Time kenne. Hatte in meinen Fragen unterstellt (nicht ausgeschlossen), dass es in neueren MS-Betriebssystemen (WIN10) weitere "Datums-Erweiterungen" gibt, um zu erkennen, ob eine Datei nachträglich nochmals geöffnet/geändert wurde. In der Pascal-Hilfe konnte ich nichts finden.
Nach der Antwort von Holgers zu schließen gibt es nur EIN Filedatum. Erstell- oder Aufnahmedatum sind offenbar Parameter in den Bilddateien (jpg).
2. Das Wort " letzte Änderung" in der StringGridtabelle meines Programms (gemäß dem gezeigten Bild) ist eine von mir gewählte Überschrift; hat also keine verbindliche Aussagekraft und nichts mit Microsoft-Vokabular zu tun.
3. Was mich irritierte und nicht verstehe ist, dass Microsoft bei Bilddateien einen Sonderweg geht und nicht das "offizielle" (normale) Filedatum anzeigt. Sowohl der TotalCommander als auch der FreeCommander verhält sich hier anders. Dieses "Sonderverhalten" im Explorer ist m.E sehr ärgerlich und schafft die Probleme. Da bei Windows-Nutzern die Verwendung des MS-Explorer überwiegt, ist eine File-Datumsänderung bei Bilddateien ungeeignet, um im Verzeichnis eine neue Bild-Sortierung zu erreichen; es sei denn, man ändert auch das Datum im jpg-Bildheader. Das wäre mein Ziel.
Meine Frage ist somit neu: hat jemand eine fertige Befehlsfolge um das Exif-Datum in Bildern zu ändern (ggf. nur jpg). Unter
www.waimea.de/downlo...EXIF-Datenformat.pdf
wird die jpg-Struktur beschrieben, erfordert aber eine umfassende Datei-Analyse. Aus dem pdf-Dokument geht hervor, dass der jpg-Header sich teilweise des tif-Headers bedient.
Um nochmals deutlich zu machen, dass hinter meinen Fragen eine konkrete Aufgabe besteht, hier nochmals das Problem:
Ich erhalte für DIA-Shows von mehreren Personen Bilder (von unterschiedlichen Kameratypen oder Handys). Beim Zusammenfügen der Bilder ist der Alphaname zur Sortierung demzufolge ungeeignet. Bleibt das Datum. Selbst wenn auch die Kamerazeiten häufig von einander abweichen, ist die Differenzeit zur einer angenommenenn Basiszeit eine Konstante. Wird diese ermittelt, können alle Bild-Zeiten dieser Kamera korrigiert werden. Soviel nochmals zur Aufgabe. Eigentlich eine Anforderung, die andere schon gelöst haben sollten. Insoweit hoffe ich noch auf hilfreichen Code.
Nachtrag: sehe gerade: Frühlingsrolle schreibt: Zitat: | Die Funktion SetFileTime() kann mehr als ein Datum ändern. |
Gibt es da ein Codebeispiel und löst dieser Funktion mein Problem? Woher weiß die Funktion, wenn sie nur das Handle hat, dass es sich um eine Bilddatei handelt?
Gruß hRb
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 01.05.19 00:38
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
icho2099
Beiträge: 101
Erhaltene Danke: 12
WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005, FPC
|
Verfasst: Mi 01.05.19 08:57
|
|
Holgerx
Beiträge: 63
Erhaltene Danke: 27
Win95 - Win11 / MSServer2000 - MSServer2019
Delphi 6pro / XE4
|
Verfasst: Mi 01.05.19 09:20
Hmm..
Im FileSystem von Windows hat jede Datei, unabhängig vom Inhalt die 3 Zeitstempel 'CreationTime', 'LastAccessTime' und 'LastWriteTime'.
Diese werden von TotalCommander oder FreeCommander angezeigt und auch immer vom Explorer, wenn dieser (umständlich) umkonfiguriert wurde.
Leider geht hier Microsoft mit seinem Explorer einen anderen Weg:
Sie meinen, anhand des Dateitypes (des Verzeichnisinhaltes) andere Infos anzuzeigen.
Z.B. bei Bildern Informationen aus den EXIF Daten oder bei Videos deren Auflösung.
(Wie man das dem Explorer abgewöhnen kann, kannst Du im Internet googlen)
Wenn Du nun nur mit den 3 FileTimes arbeiten möchtest, dann kannst Du diese über dein SearchRec auslesen.
Die Zeitangaben befinden sich dort unter
TSearchRec.FindData.ftCreationTime
TSearchRec.FindData.ftLastAccessTime
TSearchRec.FindData.ftLastWriteTime
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| function FileTimeToDateTime(AFileTime : TFileTime): TDateTime; var SystemTime: TSystemTime; LocalTime : TFileTime; begin FileTimeToLocalFileTime(AFileTime,LocalTime); FileTimeToSystemTime(LocalTime,SystemTime); result := SystemTimeToDateTime(SystemTime); end;
procedure TForm1.ReadFileTime(AFileName: string); var SR: TSearchRec; tmpDateTime : TDateTime; begin Edit1.Text := AFileName; if FindFirst(AFileName,faAnyFile,SR) = 0 then begin
tmpDateTime := FileTimeToDateTime(SR.FindData.ftCreationTime); DateTimePicker_DateCreation.Date := DateOf(tmpDateTime); DateTimePicker_TimeCreation.Time := TimeOf(tmpDateTime);
tmpDateTime := FileTimeToDateTime(SR.FindData.ftLastAccessTime); DateTimePicker_DateAccess.Date := DateOf(tmpDateTime); DateTimePicker_TimeAccess.Time := TimeOf(tmpDateTime);
tmpDateTime := FileTimeToDateTime(SR.FindData.ftLastWriteTime); DateTimePicker_DateChange.Date := DateOf(tmpDateTime); DateTimePicker_TimeChange.Time := TimeOf(tmpDateTime); end; FindClose(SR); end; |
Zum Ändern kannst Du dann das erwähnte SetFileTime verwenden. Hiermit kannst Du einen oder auch alle Werte gleichzeitig ändern.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73:
| const CentiMicroSecondsPerDay = 864000000000.0; FileTimeStart = -109205; function DateTimeToLocalFileTime(Value: TDateTime): TFileTime; begin Int64(Result) := Round((Value - FileTimeStart) * CentiMicroSecondsPerDay); end;
function LocalFileTimeToDateTime(Value: TFileTime): TDateTime; begin Result := (Int64(Value) / CentiMicroSecondsPerDay) + FileTimeStart; end;
type TFileTimes = (ftLastAccess, ftLastWrite, ftCreation);
function SetFileTimesHelper(const FileName: String; const DateTime: TDateTime; Times: TFileTimes; IsUTCBased: Boolean): Boolean; var Handle: THandle; FileTime: TFileTime; LocalFileTime: TFileTime; begin Result := False;
Handle := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
if Handle <> INVALID_HANDLE_VALUE then try LocalFileTime := DateTimeToLocalFileTime(DateTime); if IsUTCBased then begin FileTime := LocalFileTime; Result := True; end else begin Result := LocalFileTimeToFileTime(LocalFileTime, FileTime); end; if Result then begin case Times of ftLastAccess: Result := SetFileTime(Handle, nil, @FileTime, nil); ftLastWrite: Result := SetFileTime(Handle, nil, nil, @FileTime); ftCreation: Result := SetFileTime(Handle, @FileTime, nil, nil); else Result := False; end; end; finally CloseHandle(Handle); end; end;
procedure TForm1.Button2Click(Sender: TObject); var tmpDateTime : TDateTime; begin tmpDateTime := DateOf(DateTimePicker_DateAccess.Date) + TimeOf(DateTimePicker_TimeAccess.Time); SetFileTimesHelper(Edit1.Text,tmpDateTime,ftLastAccess, false);
tmpDateTime := DateOf(DateTimePicker_DateChange.Date) + TimeOf(DateTimePicker_TimeChange.Time); SetFileTimesHelper(Edit1.Text,tmpDateTime,ftLastWrite, false);
tmpDateTime := DateOf(DateTimePicker_DateCreation.Date) + TimeOf(DateTimePicker_TimeCreation.Time); SetFileTimesHelper(Edit1.Text,tmpDateTime,ftCreation, false); end; |
(Den Source habe ich aus einem alten Testprogramm, und dieser stammt teilweise aus diversen Quellen des Internets )
Ich würde Dir nicht raten, die Exif-Informationen zu verändern, das könnte schwierig werden, da auch hier leider die diversen Kamerahersteller unterschiedliche Wege gehen. Auch sollten diese fest zum Foto gehörenden Informationen nicht durch dich zur Verwendung für eine Dia-Show geändert werden, da der User diese vielleicht noch in Zukunft verwenden will.
Wenn diese Dateien auf dein Laufwerk kopiert wurden, dann sollten die FileTimes eigentlich bleiben.
Nutze besser diese, die kannst Du ändern und sie werden auch von Windows selber teilweise geändert.
|
|
icho2099
Beiträge: 101
Erhaltene Danke: 12
WIN XP, WIN 7, WIN 10
Delphi 6 Prof, Delphi 2005, FPC
|
Verfasst: Do 02.05.19 07:46
Wenn man nun aber die Fotos in eine Reihenfolge bringen möchte, die der realen Zeit der Aufnahme entspricht, dann helfen die OS Zeitstempel nicht. Die geben ja nur Auskunft darüber wann die Fotos im Album abgelegt und/oder letztmalig verändert wurden.
Der Bezug zur Realzeit kann nur über den Inhalt des Fotos selber hergestellt werden, i.d.R. sind dazu die Gangabweichungen der Aufnahmegeräte zu kennen und zu berücksichtigen.
Aus meiner Sicht führt da kein Weg an den Exif-Daten vorbei, wobei ich zustimme diese nicht zu verändern sondern nur zu lesen.
Für die Zielsortierung kann dann einer der OS Stempel manipuliert werden. Ich würde auch das Korrektiv speichern, zB im Dateiname.
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: Fr 03.05.19 17:03
Zwischennachricht,
Hallo zusammen. Allen vielen Dank. Ihr seid super! Habe ein kleines Testprogramm erstellt: funktioniert bestens!
Werde es in Kürze posten. Wenn alle Zeiten identisch sein sollen, geht es vermutlich noch etwas schlanker.
Allerdings bleibt der Hinweis von icho2099 ebenso korrekt: die Änderung der 3 Zeiten hilft nicht das grundsätzlich Problem mit dem MS-Explorer zu beheben ( da Exif-Anzeige). Melde mich nochmals... (Enkelpflichten rufen)
Gruß hRb
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 04.05.19 08:12
Das Verhalten ist im Windows Explorer schon korrekt. Wenn man die Spalte Datum anzeigt (was der Standard ist), werden nach Möglichkeit die Daten dafür aus der Datei ausgelesen sofern das Dateiformat dies unterstützt.
Wenn man das reine Änderungsdatum möchte, dann muss man auch im Kontextmenü der Überschriften die entsprechende Spalte auswählen, ebenso wie Aufnahmedatum usw.:
Die meisten Benutzer dürfte das Aufnahmedatum allerdings mehr interessieren als das Änderungsdatum im Dateisystem (mich eingeschlossen) und insofern ist die Standardeinstellung schon gut so, aber man kann sie eben jederzeit ändern.
Einloggen, um Attachments anzusehen!
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: Mi 08.05.19 00:18
Hallo zusammen,
als Anlage (zip-Datei) habe ich ein kleines lauffähiges Programm angefügt (compiliert mit Berlin 10.2). Hiermit lassen sich:
- die drei Filedaten getrennt ändern
- mit einem Klick alle Filedaten ident setzen
- nur SearchRec.Time ändern
Code-Grundlage bilden die Funktionen und Prozeduren von Holgerx (hierfür Dank). Raffiniert die Befehlsfolge
Delphi-Quelltext 1: 2: 3:
| Handle := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); if Handle <> INVALID_HANDLE_VALUE then |
Hätte so etwas nie formuliert!
An meinem Programm stelle ich bei den verschiedenen Zeiten etwas eigenartiges fest und habe dafür keine Erklärung:
1. Dass das SearchRec.Time auf Grund der 32-Bit-Darstellung die Zeit auf gerade Sekunden rundet, ist bekannt. Was mir nicht klar ist, warum SearchRec.Time bei geraden Sekunden gegenüber den anderen 3 Zeiten immer 2 Sekunden abweicht (falsch anzeigt). Effekt wird erkennbar wenn man die Zeiten ändert mittels "SetLastWriteTime". Danach zeigt FileTime = SearchRec.Time zwei Sekunden zuviel an.
2. jaenicke findet das Verhalten im Windows Explorer korrekt. Ich kann dem nicht zustimmen, weil der Explorer automatisch zwischen "Datum" und "Änderungsdatum" hin und herschaltet - je nach Dateityp. Da unter Ansicht ja alle Parameter vom Anwender zu- oder weggeschaltet werden können, besteht m.E. kein Anlass zum switchen. Die Voreinstellung, die man je explizit für alle Ordner einstellen kann, sollte in allen Verzeichnissen ident sein.
3. Bin zwar mit den verschiedenen Zeiten ein wenig schlauer, leider bleibt mein Problem mit dem Exif-Datum bestehen. Mal sehen, ob ich hier noch etwas tue. Solange ich nicht zwischen meinem Programm und dem Explorer hin und herschalte und die Werte vergleiche, ist ja alles Ok.
hRb
Einloggen, um Attachments anzusehen!
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 08.05.19 05:37
Wenn es nur um deinen PC geht... Es könnte schon reichen den Default Wert (@) unter diesem Registryzweig zu deaktivieren, sprich irgendwie zu ändern:
HKLM\Software\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.jpg
Dann sollte der Windows Explorer die Exif Daten nicht mehr lesen können.
|
|
hRb
Beiträge: 269
Erhaltene Danke: 12
|
Verfasst: Fr 17.05.19 11:52
Danke für alle Beiträge. Schließe Thema hiermit ab.
hRb
|
|
|