• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

IPTC Daten aus .csv Datei in Bilder integrieren?

abgdf schrieb:
Code:
text,"text, text, text",text, text
.. Seltsam finde ich auch, daß im Mittelteil Anführungszeichen sind, in den Außenspalten aber nicht.
Die Zeile wird folgend interpretiert:
Code:
# grep -P -o "\".+\"|[^\t, ]+" <<< "text,\"text, text, text\",text, text" | tr -d \"
bzw. im file
Code:
# grep -P -o "\".+\"|[^\t, ]+" ./file.csv | tr -d \"\\
der Inhalt spielt keine Rolle
 

abgdf

Guru
Ja, das wäre logisch. Ich hatte aber auch einen Fehler gemacht: Im letzten Teil sind Punkte, keine Kommata. Das heißt:
Code:
text,"text, text, text",text. text
Und deshalb sind auch keine Anführungszeichen um die letzte Spalte. (Aha!)
Das Speicherprogramm (OpenOffice vermutlich) macht offenbar Anführungszeichen um Spalten, in denen Trennzeichen (Kommata) sind. Und keine bei Spalten, in denen keine sind.
Das mit den Punkten ist ja auch in den Beispieldaten oben, z.B.:
Code:
Violine, Hintergrund, Instrument, Musik, Musikalisch, Hölzern, Melodie	Violine. Freigestellt vor schwarzem Hintergrund. Nahaufnahme.
Einmal Kommata, einmal Punkte. Merkwürdig.

Wie auch immer: Man könnte damit umgehen. Aber einfacher und eindeutiger wäre es, wenn man "\t" oder ein anderes Zeichen, das nicht innerhalb der Spalten vorkommt, als Trennzeichen hätte. Kann doch nicht so schwer sein.
 

abgdf

Guru
Nur um mal zu zeigen, daß ich damit umgehen könnte, wenn ich müßte.
Ich benutze nicht so gern Regex, da bin ich immer nicht so sicher, was die eigentlich matcht; lieber einen kleinen Algorithmus, da hat man mehr Kontrolle:
Code:
#!/usr/bin/python
# coding: utf-8

SEPARATOR = ","

def getDummyData():
    data = """IMG_001.jpeg,"Gitarre, Saiten, Korpus, Musikinstrument, Musik, Klang, Korpus, Holz, Konzert", Spanische Konzertgitarre. Freigestellt vor weißem Hintergrund.
IMG_002.jpeg,"Violine, Hintergrund, Instrument, Musik, Musikalisch, Hölzern, Melodie",Violine. Freigestellt vor schwarzem Hintergrund. Nahaufnahme.
IMG_003.jpeg,"Piano, Konzert, Komponist, Antik, Gesang, Jazz, Melodie",Grand Piano vor schwarzem Hintergrund. Frontalansicht.
IMG_004.jpeg,"Schlagzeug, Trommel, Musik, Rock, Chrom, Becken, Konzert, Stuhl",Schlagzeug. Vogelperspektive. Freigestellt.
IMG_005.jpeg,"Elektrisch, Gitarre, Musik, Rock, Instrument, Modern, Saiten",E-Gitarre. Nahaufnahme."""
    return data.split("\n")

def getSplit(line):
    a = line.split(SEPARATOR)
    inquotes = False
    b = []
    for i in a:
        if i.startswith('"') and i.endswith('"'):
            if inquotes:
                c.append(i.rstrip('"'))
                b.append(SEPARATOR.join(c))
                inquotes = False
            else:
                b.append(i.strip('"'))
            continue
        if i.startswith('"'):
            c = []
            c.append(i.lstrip('"'))
            inquotes = True
            continue
        if i.endswith('"'):
            c.append(i.rstrip('"'))
            b.append(SEPARATOR.join(c))
            inquotes = False
            continue
        if inquotes:
            c.append(i)
        else:
            b.append(i)
    return b

a = getDummyData()

for i in a:
    i = i.rstrip("\n")
    b = getSplit(i)
    print b
Wär' natürlich blöd, wenn in den Spalten irgendwo noch weitere Anführungszeichen wären.
Wie gesagt, Tabulator als Spaltentrenner wäre besser.
 

abgdf

Guru
Offenbar wird es nun doch bei diesem Datenformat bleiben.
Anbei also wieder eine Skriptversion.

- Es wird in ein Verzeichnis "output" geschrieben. Will man das Skript nochmal verwenden, muß man erst dieses Verzeichnis wieder löschen ("rm -r output"). Das dient dazu, die Originaldateien unangetastet zu lassen, und bei dem Output nicht durcheinanderzukommen, wenn man das Skript mehrfach verwendet.

- Werden nicht die drei Spalten in der Zeile gefunden, bricht das Skript ab.

- Endet der Text (Dateiname) aus der ersten Spalte nicht auf "jpeg" oder "jpg", wird die Zeile übersprungen. Dies gilt z.B. für die Überschriftzeile. Das Skript gibt dann eine Warnung aus, läuft aber weiter.

- Wird die Bilddatei nicht gefunden, gibt es wieder eine Warnung, und die Zeile wird übersprungen. Das Skript läuft dann aber weiter.

- Gegebenenfalls sollte man sich die Meldungen des Skripts angucken, man kann die Meldungen in eine Datei schreiben lassen: "./txtintoimg.py > log.txt".

- In den Bildern wird nun in die Tags "XMP:Headline" und "XMP:Category" geschrieben. In gimp werden mir die Daten so in "Datei/Eigenschaften/Erweitert" angezeigt.

Hoffe, es geht:

Code:
#!/usr/bin/python3
# coding: utf-8

"""
txtintoimg.py 0.8 - Reads text input from a csv-file and inserts it
                    into jpgeg-image-files using exiftool.

Copyright (C) 2021, abgdf@gmx.net

License: GNU GPL (version 2 or above):

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 3 of the License, 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.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import os, sys

DATAFILE = "Beispieldatei.csv"

OUTDIR = "output"

METADATA_TAGS = {"headline" : "XMP:Headline",
                 "keywords" : "XMP:Category"}

SEPARATOR = ','

def getSplit(line):
    a = line.split(SEPARATOR)
    inquotes = False
    b = []
    for i in a:
        if i.startswith('"') and i.endswith('"'):
            if inquotes:
                c.append(i.rstrip('"'))
                b.append(SEPARATOR.join(c))
                inquotes = False
            else:
                b.append(i.strip('"'))
            continue
        if i.startswith('"'):
            c = []
            c.append(i.lstrip('"'))
            inquotes = True
            continue
        if i.endswith('"'):
            c.append(i.rstrip('"'))
            b.append(SEPARATOR.join(c))
            inquotes = False
            continue
        if inquotes:
            c.append(i)
        else:
            b.append(i)
    return b

def getDataFromFile():
    fh = open(DATAFILE, "r")
    data = fh.readlines()
    fh.close()
    return data

def warning(message, line):
    print()
    print("WARNING: " + message)
    if line:
        print("Line:")
        print(line)

def error(message, line, errorcode):
    print()
    print("ERROR: " + message)
    if line:
        print("Line:")
        print(line)
    print()
    sys.exit(errorcode)

# Main

data = getDataFromFile()

outdir = os.path.join(os.getcwd(), OUTDIR)
if os.path.exists(outdir):
    error("Output path '" + outdir +"' already exists. Nothing done.", "", 1)
else:
    os.mkdir(outdir)

linenr = 1
for i in data:
    print()
    print("Processing line number " + str(linenr) + ".")
    i = i.rstrip("\n")
    s = getSplit(i)
    if len(s) != 3:
        error("Line number " +  str(linenr) + "doesn't seem to have the correct structure (not three columns):", i, 2)
    filename = s[0]
    keywords = s[1]
    headline = s[2]
    f = filename.lower()
    if not f.endswith(".jpg") and not f.endswith(".jpeg"):
        warning('"' + filename + "\" doesn't seem to be a jpeg-Filename. Skipping line!", i)
        linenr += 1
        continue
    if not os.path.exists(filename):
        warning('File "' + filename + "\" not found. Skipping line!", i)
        linenr += 1
        continue
    execstr  = "exiftool "
    execstr += "-" + METADATA_TAGS["headline"] + "=\"" + headline + "\" "
    execstr += "-" + METADATA_TAGS["keywords"] + "=\"" + keywords + "\" "
    execstr += "-o \"" + outdir + "\" "
    execstr += filename
    print(execstr)
    print()
    os.system(execstr)
    linenr += 1
 
OP
A

Andrea70

Newbie
Hallo abgdf,

also ich bin jetzt schon überwältigt!!!
Habe das Skript ausprobiert und es läuft jetzt schon mal insofern, dass ich den "Bildtitel" sowohl in Gimp, als auch bei einer Agentur an der korrekten Stelle wiederfinde!
Super.
Nur die Schlagwörter kann ich bis jetzt noch nirgends entdecken, weder in Gimp, noch tauchen sie bei der Agentur auf.
Doch ich bin mir sicher, dass es so ist, wie du schon geschrieben hattest, dass es entweder daran liegt, dass noch die "falschen" Meta-Tags verwendet werden, oder das es Probleme mit meinen dusseligen Kommatas gibt.
Hier also erst mal die Ausgabe aus der Konsole:
Code:
studio@studio-hppaviliondesktoppc570p0xx:~/test$ ./skript.py

Processing line number 1.

WARNING: "Bildname" doesn't seem to be a jpeg-Filename. Skipping line!
Line:
Bildname,Schlagwörter,Titel für Agentur

Processing line number 2.
exiftool -XMP:Headline="Spanische Konzertgitarre. Freigestellt vor weißem Hintergrund." -XMP:Category="Gitarre, Saiten, Korpus, Musikinstrument, Musik, Klang, Korpus, Holz, Konzert" -o "/home/studio/test/output" IMG_001.jpeg

    1 image files created

Processing line number 3.
exiftool -XMP:Headline="Violine. Freigestellt vor schwarzem Hintergrund. Nahaufnahme." -XMP:Category="Violine, Hintergrund, Instrument, Musik, Musikalisch, Hölzern, Melodie" -o "/home/studio/test/output" IMG_002.jpeg

    1 image files created

Processing line number 4.
exiftool -XMP:Headline="Grand Piano vor schwarzem Hintergrund. Frontalansicht." -XMP:Category="Piano, Konzert, Komponist, Antik, Gesang, Jazz, Melodie" -o "/home/studio/test/output" IMG_003.jpeg

    1 image files created

Processing line number 5.
exiftool -XMP:Headline="Schlagzeug. Vogelperspektive. Freigestellt." -XMP:Category="Schlagzeug, Trommel, Musik, Rock, Chrom, Becken, Konzert, Stuhl" -o "/home/studio/test/output" IMG_004.jpeg

    1 image files created

Processing line number 6.
exiftool -XMP:Headline="E-Gitarre. Nahaufnahme." -XMP:Category="Elektrisch, Gitarre, Musik, Rock, Instrument, Modern, Saiten" -o "/home/studio/test/output" IMG_005.jpeg

    1 image files created

Processing line number 7.
exiftool -XMP:Headline="Triangel. Freigestellt vor weißem Hintergrund." -XMP:Category="Triangel, Musik, Musikinstrument, Dreieck, Hobby" -o "/home/studio/test/output" IMG_006.jpeg

    1 image files created

Processing line number 8.
exiftool -XMP:Headline="Kopfhörer. Makroaufnahme. Freigestellt." -XMP:Category="Kopfhörer, Musik, Erholung, Entspannung, Hobby" -o "/home/studio/test/output" IMG_007.jpeg

    1 image files created

Processing line number 9.
exiftool -XMP:Headline="Klassische Laute. Frontalansicht. Freigestellt." -XMP:Category="Laute, Klassisch, Musik, Historisch, Mittelalter, Unterhaltung" -o "/home/studio/test/output" IMG_008.jpeg

    1 image files created

Processing line number 10.
exiftool -XMP:Headline="Traditionelle Ukulele. Tiefenschärfe" -XMP:Category="Ukulele, Musik, Klassisch, Saiten, Gitarre, Traditionell, Bespannt" -o "/home/studio/test/output" IMG_009.jpeg

    1 image files created

Processing line number 11.
exiftool -XMP:Headline="Zwei Geigen auf hölzernem Untergrund." -XMP:Category="Geige, Musikinstrument, Holz, Hintergrund, Konzert, Klassizismus" -o "/home/studio/test/output" IMG_010.jpeg

    1 image files created

Danke auch an Gräfin Klara.
 

abgdf

Guru
Andrea70 schrieb:
also ich bin jetzt schon überwältigt!!!
Na, also freut mich sehr, daß es doch schonmal soweit läuft!
Andrea70 schrieb:
Nur die Schlagwörter kann ich bis jetzt noch nirgends entdecken, weder in Gimp, noch tauchen sie bei der Agentur auf.
Also, die Kommata dürften's nicht sein. :)
Also bei mir sieht das Fenster "Datei/Eigenschaften/Erweitert" in gimp 2.8.6 so aus (Screenshot):

https://www.bilder-upload.eu/bild-0fb5d0-1612452185.jpg.html

Das heißt, ich sehe das da (und kann deswegen den Fehler nicht reproduzieren).
Neuere gimp-Versionen haben auch einen "Exif-Viewer", in dem man was sehen müßte.
Auch in geeqie sehe ich es unter "Ansicht/Exif-Fenster":
Was macht man da? Hier sind die Kategorien:

https://exiftool.org/TagNames/

Ich habe "XMP" gewählt, also diese Dokumentation und darin "XMP photoshop Tags":

https://exiftool.org/TagNames/XMP.html

Weil ich die halt in gimp sehe.
Man müßte jetzt mit einer Datei und dem einzelnen exiftool-Befehl experimentieren.
Der lautet ja z.B.:
Code:
exiftool -XMP:Headline="Spanische Konzertgitarre. Freigestellt vor weißem Hintergrund." -XMP:Category="Gitarre, Saiten, Korpus, Musikinstrument, Musik, Klang, Korpus, Holz, Konzert" -o "/home/studio/test/output" IMG_001.jpeg
Also sozusagen
Code:
exiftool -XMP:Headline="..." -XMP:Category="..." ...
Statt "XMP:Category" müßte was Anderes rausgesucht werden. Solange, bis exiftool die Datei vernünftig schreibt, und man in gimp was sieht. Welcher String das sein muß, kann ich leider nicht sagen.

Vielleicht weiß jemand anders mehr? In welchen Tag schreibt man üblicherweise solche beschreibenden Schlüsselwörter rein?

Wenn Du den richtigen String hast, kannst Du das dann auch im Skript ändern. Da habe ich die Zeile(n):
Code:
METADATA_TAGS = {"headline" : "XMP:Headline",
                 "keywords" : "XMP:Category"}
Statt "XMP:Category" müßte da der neue String rein, und dann kann man das Skript damit nochmal für alle Bilder laufenlassen.

So weißt Du wenigstens, was man prinzipiell machen müßte. :roll:
 

abgdf

Guru
Hier finde ich "XMP-dc:Subject" könnte klappen. Also im Skript:
Code:
METADATA_TAGS = {"headline" : "XMP:Headline",
                 "keywords" : "XMP-dc:Subject"}
Wie ist es damit?
 

abgdf

Guru
Übrigens: Zuerst hatte ich ja "IPTC:Headline" und "IPTC:Keywords" verwendet.
Aber das hatte offenbar Probleme mit den deutschen Umlauten. Und "IPTC:Keywords" speichert nur 64 Zeichen. Manche Deiner Daten hatten aber mehr Zeichen und wurden dann abgeschnitten. Das ging so also nicht. XMP scheint moderner zu sein.
 

abgdf

Guru
Möglich wäre auch:
Code:
METADATA_TAGS = {"headline" : "XMP:Headline",
                 "keywords" : "Comment"}
Dann ist bei mir "Headline" in gimp wie gehabt in "Datei/Eigenschaften/Erweitert", und die Keywords sind dann in "Bild/Bildeigenschaften/Kommentar".

Das ginge auch.
 
OP
A

Andrea70

Newbie
@abgdf,

also das ist ja schon mal klasse! Vielen Dank dafür.
Ich werde nun sämtliche Tags ausprobieren. Das wird jedoch eine Weile dauern, weil ich das mit den Agenturen jeweils abgleichen muss.
Sobald ich da zu einem Ergebnis gekommen bin, werde ich sagen, wie es funktioniert, damit auch andere vielleicht etwas davon haben...

Andrea70
 
Oben