pettruss
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
Hallo, ich möchte JPGs per Exiftool von allen Seriennummern befreien und auf 5MP verkleinern. Letzteres kann Exiftool nicht, ich möchte aber die Bilder nicht überschreiben oder zwischenspeichern sondern mir diesen Schreib- und Lesevorgang sparen. Bei Exiftool kann man das Ausgabeverzeichnis angeben, man müßte die Ausgabe aber direkt an ein zweites Programm übergeben, das die Bilder verkleinert. Das müßte doch Standard unter Linux sein. Alternativ könnte man in eine RAM-Disk schreiben und von dort wieder lesen, das sollte schnell gehen. Allerdings ist die in der Größe stark begrenzt. Kann man mit Pipes oder so die Ausgabe von Exiftool direkt an ein anderes Programm weitergeben, und zwar so, daß man dafür nur einen Befehl benutzt und dahinter alle Bilder samt Pfad angibt, die man bearbeiten will (Drag and drop aufs Terminal)? Also etwa so (der Befehl resize und die Optionen sind fiktiv): | exiftool -SerialNumber= -LensSerialNumber= | resize -long=2560px -o /foo/bar/
|
|
ExcitedSpoon
Anmeldungsdatum: 17. Juli 2010
Beiträge: 226
Wohnort: /home/berlin
|
pettruss schrieb: Kann man mit Pipes oder so die Ausgabe von Exiftool direkt an ein anderes Programm weitergeben, und zwar so, daß man dafür nur einen Befehl benutzt und dahinter alle Bilder samt Pfad angibt, die man bearbeiten will (Drag and drop aufs Terminal)? Also etwa so (der Befehl resize und die Optionen sind fiktiv): | exiftool -SerialNumber= -LensSerialNumber= | resize -long=2560px -o /foo/bar/
|
Das geht mit der option -o - , dann schreibt exiftool nach stdout, also in deinem Fall:
| exiftool -SerialNumber= -LensSerialNumber= -o - | resize -long=2560px -o /foo/bar/
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13075
|
pettruss schrieb:
ich möchte JPGs per Exiftool von allen Seriennummern befreien und auf 5MP verkleinern. Letzteres kann Exiftool nicht, ich möchte aber die Bilder nicht überschreiben oder zwischenspeichern sondern mir diesen Schreib- und Lesevorgang sparen. Bei Exiftool kann man das Ausgabeverzeichnis angeben, man müßte die Ausgabe aber direkt an ein zweites Programm übergeben, das die Bilder verkleinert. Das müßte doch Standard unter Linux sein. Alternativ könnte man in eine RAM-Disk schreiben und von dort wieder lesen, das sollte schnell gehen. Allerdings ist die in der Größe stark begrenzt.
Ich halte diese Sorge für nicht begründet. Dein Cache ist ja bereits so etwas wie eine RAM-Disk: wenn ein Tool die geänderte Datei geschrieben hat, steht sie erst mal im Cache und das zweite Tool operiert dann auf diesen Daten. Damit wirst Du nur ein Mal IO haben, nämlich, wenn die geänderten Blöcke auf die Platte geschrieben werden. Das klappt natürlich nur, wenn Du immer ein Tool auf eine Datei loslässt und danach dann sofort das andere. Andernfalls könnten die Änderungen des ersten Programms aus dem Cache verdrängt worden sein, bevor das zweite loslegt. Du könntest das z.B. so erreichen: | find -type f -iname \*.jpg -exec exiftool -SerialNumber= -LensSerialNumber= {} \; -exec other-tool {} \;
|
Ist ein bisschen unschön, dass so viele Prozesse gestartet werden, aber man kann halt nur eins haben.
Kann man mit Pipes oder so die Ausgabe von Exiftool direkt an ein anderes Programm weitergeben, und zwar so, daß man dafür nur einen Befehl benutzt und dahinter alle Bilder samt Pfad angibt, die man bearbeiten will (Drag and drop aufs Terminal)?
Was soll denn "Drag and drop aufs Terminal" bedeuten?
Also etwa so (der Befehl resize und die Optionen sind fiktiv): | exiftool -SerialNumber= -LensSerialNumber= | resize -long=2560px -o /foo/bar/
|
Nein, das kann nicht gehen, denn falls exiftool den Inhalt des geänderten Bildes nach Stdout ausgibt, kann es nicht auf dem selben Weg den Dateinamen transportieren und erst recht nicht mehrere Dateien samt Namen übertragen.
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
rklm schrieb: pettruss schrieb:
Alternativ könnte man in eine RAM-Disk schreiben und von dort wieder lesen, das sollte schnell gehen. Allerdings ist die in der Größe stark begrenzt.
Ich halte diese Sorge für nicht begründet. Dein Cache ist ja bereits so etwas wie eine RAM-Disk: […]
Ja, aber findet da nicht eine Art Management statt? Wenn ich selber eine RAM-Disk als Ausgabeort angebe, dann schreibt exiftool da wahrscheinlich rein, bis die RAM-Disk voll ist und bricht mit einer Fehlermeldung ab, oder so.
[…] wenn ein Tool die geänderte Datei geschrieben hat, steht sie erst mal im Cache und das zweite Tool operiert dann auf diesen Daten. Damit wirst Du nur ein Mal IO haben, nämlich, wenn die geänderten Blöcke auf die Platte geschrieben werden. Das klappt natürlich nur, wenn Du immer ein Tool auf eine Datei loslässt und danach dann sofort das andere. Andernfalls könnten die Änderungen des ersten Programms aus dem Cache verdrängt worden sein, bevor das zweite loslegt. Du könntest das z.B. so erreichen: | find -type f -iname \*.jpg -exec exiftool -SerialNumber= -LensSerialNumber= {} \; -exec other-tool {} \;
|
Ist ein bisschen unschön, dass so viele Prozesse gestartet werden, aber man kann halt nur eins haben.
Stimmt, das hatte ich gar nicht bedacht, daß womöglich zuerst das eine Tool alle Dateien abarbeitet und dann erst das andere. find -type f -iname \*.jpg sucht nach Dateien vom Typ file (statt directory) mit ».jpg« im Dateinamen.
-exec … {} \; wendet »…« auf alle gefundenen Dateien an, {} ist der Platzhalter für diese Dateien, bei \; ist Schluß mit dem per exec aufgerufenen Befehl.
Interpretiere ich das so richtig? Wozu der Backslash vor *.jpg ? Wie bringe ich find dazu, die bearbeiteten Bilder in ein bestimmtes Verzeichnis zu schreiben? Von wo nimmt es die Bilder?
Was soll denn "Drag and drop aufs Terminal" bedeuten?
Normalerweise, wenn ich nur exiftool benutze, dann schreib ich Terminal exiftool -… (alle Optionen, die ich brauche) und ein Leerzeichen, dann ziehe ich vom Dateibrowser alle Dateien, die ich bearbeiten will, aufs Terminal. Ich will ja meistens nicht alle Dateien in einem Verzeichnis bearbeiten, und ich hätte keine Lust, die Dateinamen im Terminal zu tippen, auch nicht mit Tab/Vervollständigung. So spare ich es mir, die Dateien kurz in ein eigenes Arbeitsverzeichnis zu verschieben, auf das ich exiftool loslassen könnte. Danke schonmal, jetzt muß ich ein Tool finden, das Bilder verkleinert, aber das kann ja nicht schwer sein.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13075
|
pettruss schrieb: rklm schrieb:
Ich halte diese Sorge für nicht begründet. Dein Cache ist ja bereits so etwas wie eine RAM-Disk: […]
Ja, aber findet da nicht eine Art Management statt? Wenn ich selber eine RAM-Disk als Ausgabeort angebe, dann schreibt exiftool da wahrscheinlich rein, bis die RAM-Disk voll ist und bricht mit einer Fehlermeldung ab, oder so.
Mir ist nicht klar, was Du hier fragst.
Stimmt, das hatte ich gar nicht bedacht, daß womöglich zuerst das eine Tool alle Dateien abarbeitet und dann erst das andere.
Das vermeidet mein Einzeiler.
find -type f -iname \*.jpg sucht nach Dateien vom Typ file (statt directory) mit ».jpg« im Dateinamen.
-exec … {} \; wendet »…« auf alle gefundenen Dateien an, {} ist der Platzhalter für diese Dateien, bei \; ist Schluß mit dem per exec aufgerufenen Befehl.
Interpretiere ich das so richtig? Wozu der Backslash vor *.jpg ?
Damit die Shell damit keine Filename Expansion vornimmt und so die Befehlszeile ruiniert.
Wie bringe ich find dazu, die bearbeiteten Bilder in ein bestimmtes Verzeichnis zu schreiben? Von wo nimmt es die Bilder?
find nimmt die Bilder gar nicht, es findet sie ja gerade. Ich hatte jetzt angenommen, dass die Befehle auf den gefundenen Dateien direkt arbeiten sollen. Wenn Du die Ausgaben noch woanders hin kopieren willst, muss man das anders machen. Beispiel: | find ... -exec sh -c '
for file; do
target="/foo/bar/${file##*/}"
exiftool ... -o - "$file" | gm convert ... - "$target"
done
' -- {} +
|
Danke schonmal, jetzt muß ich ein Tool finden, das Bilder verkleinert, aber das kann ja nicht schwer sein.
Graphics Magick
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
rklm schrieb: pettruss schrieb: rklm schrieb:
Ich halte diese Sorge für nicht begründet. Dein Cache ist ja bereits so etwas wie eine RAM-Disk: […]
Ja, aber findet da nicht eine Art Management statt? Wenn ich selber eine RAM-Disk als Ausgabeort angebe, dann schreibt exiftool da wahrscheinlich rein, bis die RAM-Disk voll ist und bricht mit einer Fehlermeldung ab, oder so.
Mir ist nicht klar, was Du hier fragst.
Ich wollte nur sagen, daß bei Angabe einer RAM-Disk als Zielverzeichnis der Fall eintreten könnte, daß da nicht alle bearbeiteten Dateien reinpassen. Das trifft auf den Cache dann auch zu, aber der ist ja nicht das Ziel. Wenn der voll ist, dann wird der Rechner langsam, denke ich mal. Wenn die RAM-Disk voll ist, dann dürfte exiftool abbrechen. Aber ist nicht so wichtig, das mit der RAM-Disk war ja nur eine »Nebenidee«, die nicht weiterverfolgt wird. find nimmt die Bilder gar nicht, es findet sie ja gerade. Ich hatte jetzt angenommen, dass die Befehle auf den gefundenen Dateien direkt arbeiten sollen. Wenn Du die Ausgaben noch woanders hin kopieren willst, muss man das anders machen. Beispiel:
| find ... -exec sh -c '
for file; do
target="/foo/bar/${file##*/}"
exiftool ... -o - "$file" | gm convert ... - "$target"
done
' -- {} +
|
Da blicke ich jetzt nicht mehr durch. Was genau macht das Skript (die drei Punkte, sh und c kenne ich nicht)? Was meinst du mit »woanders hin kopieren«? Die Ausgabe soll direkt dort landen. Oder anders: Die Befehle/Tools sollen die gefundenen Dateien direkt bearbeiten, aber das Ergebnis gleich auf die SD-Karte schreiben, nicht ins Quellverzeichnis. Dann spart man sich das Schreiben auf die Festplatte und das erneute Lesen von dort. Außerdem will ich die gefundenen Dateien nicht überschreiben.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13075
|
pettruss schrieb: rklm schrieb:
Wenn Du die Ausgaben noch woanders hin kopieren willst, muss man das anders machen. Beispiel: | find ... -exec sh -c '
for file; do
target="/foo/bar/${file##*/}"
exiftool ... -o - "$file" | gm convert ... - "$target"
done
' -- {} +
|
Da blicke ich jetzt nicht mehr durch. Was genau macht das Skript (die drei Punkte, sh und c kenne ich nicht)?
Die drei Punkte sind eine Ellipse. sh ist die Bourne-Shell und "-c" ist eine Option, die von allen Shells der Bourne-Familie verstanden wird.
Was meinst du mit »woanders hin kopieren«? Die Ausgabe soll direkt dort landen. Oder anders: Die Befehle/Tools sollen die gefundenen Dateien direkt bearbeiten, aber das Ergebnis gleich auf die SD-Karte schreiben, nicht ins Quellverzeichnis.
Also doch woanders hin kopieren (im Ggs. zu an der Stelle bearbeiten).
Dann spart man sich das Schreiben auf die Festplatte und das erneute Lesen von dort. Außerdem will ich die gefundenen Dateien nicht überschreiben.
Ja. Genau die Anforderung erfüllt das Skript.
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
rklm schrieb: pettruss schrieb: rklm schrieb:
Wenn Du die Ausgaben noch woanders hin kopieren willst, muss man das anders machen. Beispiel: | find ... -exec sh -c '
for file; do
target="/foo/bar/${file##*/}"
exiftool ... -o - "$file" | gm convert ... - "$target"
done
' -- {} +
|
Da blicke ich jetzt nicht mehr durch. Was genau macht das Skript (die drei Punkte, sh und c kenne ich nicht)?
Die drei Punkte sind eine Ellipse.
Also doch. Dann schreib ich da statt der Punkte meinen eigenen Kram hin? Oben bei find meine ich, bei exiftool und convert sowieso. Wofür steht -o - "$file" nach exiftool ?
Also doch woanders hin kopieren (im Ggs. zu an der Stelle bearbeiten).
Ok, kopieren klang für mich so, als würden die Dateien erst an der Stelle bearbeitet und danach kopiert.
Dann spart man sich das Schreiben auf die Festplatte und das erneute Lesen von dort. Außerdem will ich die gefundenen Dateien nicht überschreiben.
Ja. Genau die Anforderung erfüllt das Skript.
Super, danke nochmal.
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
Einfach ausprobieren statt viel fragen … Folgendes tut, was ich möchte (die Bilder auf 2560px an der langen Kante verkleinern):
| find -type f -iname \*.jpg -exec sh -c '
for file; do
target="/media/pettruss/sd-karte/ordner/${file##*/}"
exiftool -SerialNumber= -InternalSerialNumber= -LensSerialNumber= -ExtenderSerialNumber= -FlashSerialNumber= -o - "$file" | gm convert -geometry 2560x2560 - "$target"
done
' -- {} +
|
Aber mich würde noch interessieren, was die einzelnen Skriptteile machen, also
target="…" (eine Variable definieren?),
${file##*/} (die gefundenen Dateinamen in einer zweiten Variable speichern?),
-o - "$file" ,
- "$target" und
-- {} + .
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
pettruss schrieb: Aber mich würde noch interessieren, was die einzelnen Skriptteile machen, also
Klar, eine einfache Variablenzuweisung. Das ist eine Parameter Expansion. Zu verstehen als 2 Parameter zu exiftool: -o - für "Ausgangsdatei=/dev/stdout" und FILE, also den zu lesenden Dateinamen. Zu verstehen als 2 Parameter zu gm convert, nämlich "input-file" und "output-file". Beachte: "-" steht hier (wie auch sonst oft) für das Standard-Device. Die Option "–" beendet die Optionen. Was danach kommt, ist nur noch der Dateiname, auch wenn er mit "-" beginnt. Der Rest gehört zu find. LG, track
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13075
|
track schrieb:
[...]
Einige der Punkte kann man recht einfach über die Dokumentation der benutzten Programme klären.
Die Option "–" beendet die Optionen. Was danach kommt, ist nur noch der Dateiname, auch wenn er mit "-" beginnt.
Es wäre noch anzumerken, dass die Schleife mit for nicht richtig funktionieren würde, wenn man "–" weglässt: $ sh -c 'for x; do echo "$x"; done' $(seq 1 5)
2
3
4
5
$ sh -c 'for x; do echo "$x"; done' -- $(seq 1 5)
1
2
3
4
5
$
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
Danke. Es ist zwar mehr Code nötig, als ich zuerst erwartet hab, aber wenn man etwas genauer hinschaut, ist es gar nicht mal so aufwendig, wie es auf den ersten Blick aussieht.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13075
|
pettruss schrieb: Danke.
Wenn das Thema für Dich erledigt ist, bitte als "gelöst" markieren. Danke!
|
pettruss
(Themenstarter)
Anmeldungsdatum: 26. Juni 2010
Beiträge: 207
|
|