… wollte ich hier nen Tourbericht von meiner Junitour mit der GrünenWelle niederschreiben, doch irgendwie passte mir das alles nicht, wie das so aussah, was für ein Aufwand das war, und sowieso.
So ist es nun die Vorstellung eines kleinen Skriptes um solch Berichte semiautomatisiert herzustellen. Bei uns im Büro würde sowas 10tausende von Euro kosten und monatelang dauern – klar, Validation ist wichtig, und Planung auch – doch so viel Zeit habe ich nicht.
Hingerotzt in BASH, laeuft somit ziemlich ueberall. Nix modern, nix Container oder Java. Einfach noch ein Skript, welches mir die Arbeit einfacher macht.
Workflow ist folgender:
Fotos erstellen – nach hause bringen – rauf auf den Rechner – mit beliebiegem Fototool bearbeiten in gewünschte Reihenfolge bringen und folgende Exif/IPTC Felder füllen:
Titel/Title – Überschrift für das Bild
Beschreibung / Description – Beschreibung zum Bild
Dann Fotos nach Reihenfolge in ein Verzeichnis exportieren und „./picturestory_generate DEINEFOTOS* > DEINHTMLFILE.html“ aufrufen, etwas warten und fertig.
Klingt einfach? Nein? Ja, dann benutze weiter irgend ein Klickieklicktool. Mir ist das zu viel Aufwand, zu viel Eierlegendewollmilchsau. Ich habs eben wieder probiert mit einem dieser „Generier Dir ganz schnell selbst ne Webseite mit Deinen Fotos“-Tools. Lange nicht mehr so viel geflucht über Performance, Bedienung und Ergebnis. Da mach selbst ich als alter Mann ohne Programmierkenntnisse schneller – ja, ich machs nicht schön, aber zweckmäßig ; -)
Ich hab mir die Farben und das Layout im Skript mit CSS eingestellt, dies kann man schnell anpassen. Das Skript geht dann mit exiftool (https://exiftool.org/) alle Fotos durch und packt sie untereinander. Sehr breite Fotos werden über die ganze Breite des Browsers dargestellt. Vorangestellt jeweils der Titel und die Beschreibung. Fotos mit einer kleineren Breiten/Höhenratio werden neben Titel und Beschreibung dargestellt. Abwechselnd links und rechts.
Sollte ein Foto nicht als Panorama erkannt werden, weil die Ratioerkennung dazu neigt es als „Text-Daneben“-Foto darzustellen, so kann dem Foto in den Schlagwörter / Keywords einfach das Wort PANORAMA hinzugefügt werden. Schon erscheint das Foto auf ganzer Browserbreite. Bei Videos speichert zumindest mein verwendetes Tool (Apple Fotos) keine Keywords in den Videos. Das Skript unterstützt trotzdem selbiges für Videos, man kann aber dem Titel eines Videos auch ein ! hinzufügen. Hat den selben Effekt: Es wird über die volle browserbreite dargestellt.
Ja, ist irgendwie insgesamt sicherlich „ich war auch mal Unixadmin“-Rotz. Aber Rotz, der mir das Leben erleichtert. Und neudeutsch sehr lightweight-code, der da generiert wird ; )
Bei Fragen: Fragen. Beschreibungstexte muss man übrigens noch selber schreiben, is ja nur SEMIautomatisiert ; -)
UPDATE 8.7.2020: Ich hab das mal überarbeitet, damit es auch nen Video einbinden kann. Dazu etwas aufgeräumt und CSS/Konfig in getrennte Datei, damit man diese zu den einzelnen Berichten mit ablegen/editieren kann.
UPDATE 9.7.2020: Mir war die Performance nicht so recht. Mit dieser Version generiert das Skript mit ca fünfacher Geschwindigkeit. Dafür gibt es zur zeit die Einschränkung, dass keine Anführungszeichen mehr in Titel und beschreibung verwendet werden können. Des weiteren ist „lazy loading“ aktiviert. bei modernen Browsern werden die vielen Daten nun nacheinander geladen. Sollte angenehmer für den Betrachter sein.
./picturestory_generate.sh:
# ./picturestory_generate.sh
#
# Generiert aus einer Liste von Fotos/Videos eine Webseite, die auch IPTC Titel und Beschreibung einfuegt.
# Alles andere an Tools war mir zu komplex um mal eben einen Radfahrbericht zu erstellen.
#
# 6.7.2020 v1 Nur Fotos
# 8.7.2020 v2 Inkl Video und CSS dediziert, aufgeraeumt
# 8.7.2020 v2.1 Performanceoptimierung um das 5fache (exiftool nur 1x pro Datei, Pipe in Datei und Vars einsourcen)
#
# Benoetigt exiftool https://exiftool.org/
# und ./picturestory_css
# Datein muessen in Reihenfolge alphabetisch vorliegen: bild01.jpg bild02.jpg bild03.m4v bild05.jpg ...
#
# ./picturestory_generate SOT_Walsrode* > SOT_Walsrode.html
# Ohne Angabe von Datein gibt es Info ueber Benutzung und keine Ausfuehrung
if [ $# -ge 1 ]; then
# Config und CSS
. ./picturestory.config
# Wir generieren mal den Anfang vom HTML ....
echo "<!DOCTYPE html><html><head><meta http-equiv=content-type content=text/html; charset=utf-8><title> $TITEL </title><style>"
echo $CSSFORMAT
echo "</style></head>"
# Wir (wer is eigentlich Wir?) generieren mal nen Block fuer Titel und Anreisser
echo "<h1> $TITEL </h1>"
echo "<h4>"
echo "<i><b>$ANREISSER</i></b>"
echo "</h4>"
# Fuer jede angegebene Datei generieren wir ...
for bild in "$@"; do
exiftool -Title -Description -ImageHeight -ImageWidth -Keywords "$bild" | awk -F ": " '{ print "IPTC"NR"=\""$2"\";" };' > /tmp/iptc.tmp
. /tmp/iptc.tmp
TITLE=$IPTC1
DESCRIPTION=$IPTC2
HOEHE=$IPTC3
BREITE=$IPTC4
KEYWOERTER=$IPTC5
#DESCRIPTION=`exiftool -Description "$bild" | awk -F " : " '{ print $2 };'`
#TITLE=`exiftool -Title "$bild" | awk -F " : " '{ print $2 };'`
#HOEHE=`exiftool -ImageHeight "$bild" | awk -F ": " '{ print $2 };'`
#BREITE=`exiftool -ImageWidth "$bild" | awk -F ": " '{ print $2 };'`
#KEYWOERTER=`exiftool -Keywords "$bild"`
RATIO=`echo $((BREITE / HOEHE))`
# Wenn jpg dann 0 ansonsten 1 (Videoeinbettung)
echo $bild | grep ".jpg" >/dev/null 2>&1
if [ $? -eq 0 ]; then
DATEITYP=0
else
DATEITYP=1
fi
# Panoramacheck nach Ratio oder overruled durch Definition PANORAMA in Keywords oder ! in Titel (Apple Fotos packt keine Keywords in Video)
if [ $RATIO -lt 2 ]; then
PANO=0
else
PANO=1
fi
echo $KEYWOERTER | grep "PANORAMA" >/dev/null 2>&1
if [ $? -eq 0 ]; then
PANO=1
fi
echo $TITLE | grep "!" >/dev/null 2>&1
if [ $? -eq 0 ]; then
PANO=1
fi
echo " "
echo " "
# Wenn Foto ...
if [ $DATEITYP -eq 0 ]; then
# ... und kein Panorama ...
if [ $PANO -eq 0 ]; then
# ... dann jeweils rechts/links in Tabellenform darstellen
if [ $RECHTSLINKS -eq 0 ]; then
echo "<table><tr><td width=30%><h2 style=padding-left:60px; padding-right:0px> $TITLE </H2>"
echo "<p style=padding-left:60px; padding-right:0px> $DESCRIPTION </p> </td><td width=70%>"
echo "<img align=right src='$bild' loading=lazy width=70%></td></tr></table>"
RECHTSLINKS=1
else
echo "<div><table><tr><td width=70%><img align=left src='$bild' loading=lazy width=70%>"
echo "</td><td><h2 style=padding-left:0px; padding-right:0px> $TITLE </H2>"
echo "<p style=padding-left:00px; padding-right:0px> $DESCRIPTION </p></td></tr></table></div>"
RECHTSLINKS=0
fi
# von rechtslinks
# Oder in voller Breite
else
echo "<h2> $TITLE </H2><p padding-right: 30%;> $DESCRIPTION </p><div><img src='$bild' loading=lazy width=100%></div>"
fi
# von Ratiowert
# else von Dateityp - Es folgt Video
else
echo "<h2> $TITLE </H2><p padding-right: 30%;> $DESCRIPTION </p><center><video src=$bild"
if [ $PANO -eq 0 ]; then
echo " width=50% controls>"
else
echo " width=100% controls>"
fi
echo "Ihr Browser kann dieses Video nicht wiedergeben.<br/>Sie können es unter <a href="#">$bild</a> abrufen."
echo "</video></center>"
fi
# von Dateityp
done
# schleife jede Datei
# Wir generierend das Ende von HTML...
echo "<h3>Diese kleine FotoLoveStory wurde generiert mit 'picturestory_generate'. Ein klitzekleines Skript von Sven.<br>"
echo "Siehe <a href=https://www.lieblos.de/?p=3769>https://www.lieblos.de</A>, "
echo `date`
echo "</h3></body></html>"
# Benutzungshinweis
else
echo "./picturestory_generate PICTUREFILES "
echo ""
echo "Beispiel: ./generate_picturestory SOT_Walsrode* > SOT_Walsrode.html"
echo ""
echo "Fotos muessen als *.jpg in alphabetischer Reihenfolge abgelegt sein."
echo "Known-Bug: Anfuehrungszeichen in Titel und Beschreibung funktionieren nicht, dafür nun 5x schneller!"
echo "Fuer jeden Bericht kann ein eigenes picturestory.config verwendet werden."
fi
# Overall
rm /tmp/iptc.tmp
Und hier die Configdatei ./picturestory.config für meinen Bericht aus Walsrode, die kann dann angepasst werden:
#!/bin/bash
# Inlay fuer picturestory_generate
# EINSTELLUNGEN
TITEL="Im Juni 2020 mit der GrünenWelle rund um Walsrode."
ANREISSER="SOT - Sven on Tour, 6 Tage, 750km"
RECHTSLINKS=0
# CSS FORMATIERUNG
CSSFORMAT="
body {
background-color: #424242;
color: white;
margin-left: 50px;
margin-right: 50px;
}
h1 {
font-size: 400%;
color: #088A29;
color: #31B404;
padding-left: 50px;
padding-top: 20px;
padding-bottom: 0px;
}
h2 {
color: white;
font-size: 200%;
text-align: left;
}
p {
color: #E6E6E6;
font-size: 150%;
padding-right: 30%;
}
div {
padding-bottom: 50px;
}
img {
border:solid #2E2E2E 1px;
}
video {
padding-bottom: 50px;
}
h3 {
color: #6E6E6E;
font-size: 90%;
}
h4 {
padding-top: 20px;
color: #5E5E5E;
font-size: 150%;
padding-left: 100px;
}
a:link {
color: #6E6E6E;
font-size: 90%;
}
a:hover {
color: #6E6E6E;
font-size: 90%;
}
a:visited {
color: #6E6E6E;
font-size: 90%;
}
a:active {
color: #6E6E6E;
font-size: 90%;
}
"