Effektiv billedbehandling på Linux' kommandolinje

Jeg var i weekenden ude til et glimrende sponsorstævne hos Greve Karate. Forskellige personer ønskede billeder og gerne mange, så jeg endte med at tage 1500 billeder på en dag. Billderne reducerede jeg derefter ned til 600. Efterfølgende skulle billederne skaleres og uploades, og her er det genialt med en Linux-maskine. Det vil jeg vise et par eksempler på i det følgende.

ImageMagick er et program, der har mange år på bagen, men det er stadig super godt. Programmet kan MASSER af sjove ting, og i dette blogindlæg kradser jeg kun lige i overfladen.
Jeg gennemgår eksemplerne så de fleste kan følge det, for der er noget, der er meget anvendeligt for alle med en Linux-maskine.

Alle mine billeder hedder DSC_NNNN.JPG efter de er hentet ind på computeren, og derfor kan jeg på kommando-linjen tilgå filerne en ad gangen med en for-løkke i Bash-shellen:

for i in $( ls DSC_*.JPG); do echo $i; done

Kommandoen der udføres på hver fil er echo og filnavnet kommer ind med $i.
Resultatet af at køre programmet er
DSC_6060.JPG
DSC_6062.JPG
DSC_6063.JPG
DSC_6070.JPG
… osv

For at skalerere f.eks. “DSC_6060.JPG” til 1024 pixels (på længste led) kommer “convert” i brug - det er en del af ImageMagick. “-resize 1024” giver 1024 pixels og det næste argument er ind-filnavnet og sidste argument er ud-filnavnet:

convert -resize 1024 DSC_6060.JPG re_DSC_6060.JPG

Dvs. “DSC_6060.JPG” bliver konverteret til “re_DSC_6060.JPG”

Det kan jeg nu sætte sammen med for-løkken ovenfor og få konverteret alle mine billeder

for i in $( ls DSC_*.JPG); do convert -resize 1024 $i  re_$i; echo $i; done

Igen skrives ind-filnavnet ud med echo $i, men ydermere laver jeg “convert -resize 1024” på filen.
Med 600 billeder er det sejt at en linie kode kan lave hele konverteringen. Skal man lægge billeder på Internettet kan man often spare en masse upload-tid da folk oftest kan bruge ret små billeder uden problemet.

Jeg går lidt videre. Jeg vil nu også gerne have en titel på hvert billede, hvor der skal stå “Greve Karate” i nederste venstre hjørne. Vi kan nemt få dette med at give “convert” lidt ekstra argumenter
-draw "gravity southwest fill white text 11,11 'Greve Karate' - dvs. skriv i syd-vest (nederste venstre hjørne) i hvid skrift og hæv det lige 11 pixels fra hjørnet i begge retninger:

for i in $( ls DSC_*.JPG); do \
  convert -resize 1024 \
  -draw "gravity southwest fill white text 11,11 'Greve Karate' " $i re_$i; \
  echo $i; done

Her har jeg brækket linjen op med "\" af hensyn til læsbarheden. Et af billederne (med datter Louise) bliver således:

Illustration: Privatfoto

Klik på billedet for at se teksten. Synes man at fonten er for lille tilføjes f.eks. "-pointsize 20".

Der er yderligere inspiration angående “watermarking” på dette link.

Jeg er uhyre doven mht. repetitivt arbejde. Her skal computeren bare på arbejde, og der er som vist ikke så svært at lave en enkelt linie kode som kan få Linux maskinen til at rekode alle mine billeder. Kom bare i gang med lignende sjove ting.

/pto

Kommentarer (29)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Malte Christensen

Problemet er blot, at Linux desværre ikke slår til, hvis udgangspunktet er RAW fotos, som skal retouches. Her er der intet, som slår Adobe værktøjerne (nej, heller ikk rawstudio og gimp). Desværre.
Og vi er nok mange, som aldrig vill drømme om at optage i JPG format.

  • 2
  • 3
Peter Brodersen

Af ren nysgerrighed: Er der nogen grund til, at du hiver ls ind over? DSC_*.JPG vil alligevel blive expandet af din shell som selvstændige argumenter allerede før, de rammer ls.

For eksempel vil

echo DSC_*.JPG

og

ls DSC_*.JPG

give samme output. Naturligvis forudsat at der er nogen filer, der matcher din glob - er der ikke, vil echo blot outputte "DSC_*.JPG", og ls vil spytte en fejl ud til stderr.

Skulle man have filnavne med mellemrum i, så er ls-løsningen også uhensigtsmæssig, idet filnavnet bliver brudt op i flere argumenter:

$ touch 'foo.txt' 'bar baz.txt' 'qu"ux.txt'  
   
$ for i in *.txt; do echo $i; done  
bar baz.txt  
foo.txt  
qu"ux.txt  
   
$ for i in *.txt; do ls "$i"; done  
bar baz.txt  
foo.txt  
qu"ux.txt  
   
$ for i in $( ls *.txt); do echo $i; done  
bar  
baz.txt  
foo.txt  
qu"ux.txt  
   
$ for i in $( ls *.txt); do ls "$i"; done  
ls: cannot access bar: No such file or directory  
ls: cannot access baz.txt: No such file or directory  
foo.txt  
qu"ux.txt

Hvis man i øvrigt arbejder på en kopi af billederne, så kan mogrify også bruges. mogrify er en del af ImageMagick og virker med samme argumenter som convert, men overskriver de eksisterende filer.

mogrify -resize 1024 \  
  -draw "gravity southwest fill white text 11,11 'Greve Karate' " \  
  DSC_*.JPG

.. og så behøver vi ikke at starte convert op individuelt for hver eneste fil. Dog er det næppe det, som gør den store ressourceforskel.

  • 9
  • 0
Peter Brodersen

Ud over at ImageMagick normalt følger med en del linux-distributioner og ellers er let at hive ind, så kan man fx også lave følgende løkke under Windows (testet under en helt almindelig cmd.exe under Windows XP), hvis man ikke vil bruge mogrify:

for %i in (DSC_*.JPG) do  
  @convert  
  -resize 1024  
  -draw "gravity southwest fill white text 11,11 'Greve Karate' " %i re_%i  
  && echo %i

(erstat linjeskift med mellemrum)

Et par faldgruber:

Windows globber som udgangspunkt ikke på kommandolinjen, så echo DSC_*.JPG vil i sig selv ikke give en liste over filerne. Det er her, for kommer ind i billedet.

Derudover bliver for-globben tilsyneladende populeret løbende, hvilket kan give nogle ret mærkelige resultater. Har man fx filerne foo.txt og bar.txt og afvikler:

for %i in (*.txt) do @copy %i re_%i

.. ender man med filerne foo.txt, bar.txt, re_foo.txt, re_bar.txt og re_re_foo.txt (!) - jeg tror, det er her, de unge ville sige "WAT".

Dette er dog ikke et problem i vores convert-eksempel, idet de nye filer (der præfixes med re_) alligevel ikke vil matche DSC_*.JPG og dermed ikke ryger ind i løkken.

  • 10
  • 0
Morten Jensen

Jeg tager en del billeder under vand, hvor specielt whitebalance er et rpoblem...
Jeg bruger ufraw til at behandle raw formater. Ufraw har ogsaa en batch funktion some du kan bruge til at konvertere .nef eller lignende til .jpg fra komandolinien.

Saa Linux fungerer fint til billedredigering.

  • 4
  • 1
Søren Reinke

Morten, bare at auto konvertere undervandsbilleders hvid balance, giver ikke det optimale resultat.

Personligt bruger jeg Lightroom fra Adobe, da jeg så specifikt, ud fra min erfaring, kan fortælle hvad der er hvidt. Det synes jeg giver det bedste resultat.

Batch konvertering kan dog sagtens bruges så man har en bedre mulighed for grovsortering, for derefter at gøre det manuelt.

  • 1
  • 0
Esben Madsen

Jeg bruger selv darktable til at sortere og tilpasse mine raw-billeder på linux... det er et open source forsøg på at lave noget i stil med adobes lightroom og fungerer ganske ok... fra darktable eksporterer jeg full-size jpg i kvalitet 100 til en mappe der hedder full, og har så smidt flg. i .bash_aliases som jeg kører efter eksporten:

alias imgOrderConvert='echo "copying large" && mkdir -p large && cp full/* large/ && echo "Converting..." && mogrify -monitor -quality 85 large/*.jpg ; echo "copying medium" && mkdir -p medium && cp -r full/* medium/ && echo "Converting..." && mogrify -monitor -quality 85 -resize 800x800 medium/*.jpg'
  • 2
  • 0
Dennis Andersen

@Malte Christensen: Jeg har nu aldrig haft problemer med at redigerer mine raw billeder på min Linux maskine, KanalTux.dk er desværre ikke længere men deres videor ligger vist på Youtube de viste nogle ganske gode værktøjer og der findes et hav af gode værktøjer til raw.
Jeg har enda haft en lille Linux box kørende på et tidspunkt som via commandline tool konverterede raw til png til brug på web o.lign.

  • 0
  • 0
Morten Jensen

Og det er saa ogsaa hvad jeg goer. Jeg laver en batch convertering for at se hvad der kom ud af mine anstrengelser. Vi dykker i Gibraltar-straedet, saa vi gaar normalt til mellem 38-48 meter. Vi har ofte 1-2 knob stroem paa den dybde.
Det betyder at jeg har rimeligt travlt med at tage billeder, at jeg holder fast i en klippe og at der ikke er ret meget lys tilbage. Automatisk convertering kan kun vise hvilke beilleder jeg ikke skal bruge mere tid paa :-)

  • 0
  • 0
Poul Pedersen

Så mangler vi bare lige et script der kan sortere de gode billeder fra, når man nu har været ude og skyde 10kklik motorsport en weekend. :-)

For realistisk set, så er der jo max 100 seværdige billeder, uanset hvor meget man trykker på udløseren en hel weekend.

Og så skal der så lige også beskæres, justeres levels, shadows+highlights, fjernes sensorpletter fra himlen, støjreduceres, sharpenes og klones uheldige elementer så begynder det at ligne noget. ;-)

  • 0
  • 0
Morten Friberg

Hvis der skulle sidde nogle og mangle et GUI-værktøj i Windows med samme funktionalitet, så er Irfanviews batch-funktionalitet ganske glimrende. Men jeg indrømmer gerne, at one-liners er sjovere :-)

  • 0
  • 0
Jonas Karlsson

Jeg er hobbyfotograf og linuxbruger. Til formålet har jeg anvendt Darktable (opensource) og Corel Aftershot, der også fås til Linux. Det må da give god mening at sammenligne med Adobe værktøjerne.

Jeg holder i øvrigt af HDR fotografering, men jeg vil bruge min tid på at fotografere frem for at efterbehandle. Der findes en del GUI programmer til den slags fotografering. Selvom der er batch modes skal man klikke en masse for at producere nogle få billeder - så det egner sig ikke til 300 feriefotos.

Hvis det har interesse for nogen, er der et fantastisk (bash) scripted work flow fra denne side: linuxdarkroom.tassy.net/
resultaterne er formidable, og man slipper for mange timer foran skærmen.

  • 1
  • 0
Torben Jensen

Og hvis du i forvejen har rigtig mange digitale billeder, og gerne vil holde lidt bedre styr på bilderne, end bare lave en folder af givent navn, kan jhead anbefales.

Den kan rename billeder efter dato og tidspunkt billedet er taget på.

jhead -nImage%Y%m%d-%H%M%S *.jpg

og dit billeder får nyt navn og hedder nu f.eks.

Image20111014-172449.jpg

http://www.sentex.net/~mwandel/jhead/

  • 3
  • 0
Jens Dalsgaard Nielsen

jhead er smart, men hvis du har billeder fra flere kameraer kan du risikere at to billeder er taget samme sekund.

Jeg bruger først at navngive dem med deres md5sum og dernæst efter yymmddhhmmss+counter så jeg kan have op til 10 eller 100 pr sekund. Ret nemt i awk med associative arrays

  • 1
  • 0
Jørgen L. Sørensen

For realistisk set, så er der jo max 100 seværdige billeder, uanset hvor meget man trykker på udløseren en hel weekend.

Og så skal der så lige også beskæres, justeres levels, shadows+highlights, fjernes sensorpletter fra himlen, støjreduceres, sharpenes og klones uheldige elementer så begynder det at ligne noget. ;-)

Den første del er jeg ret enig med dig i :-)

Den anden del kan man godt forsvare at springe lettere hen over, hvis det "kun" er for at vise en foto-historie om et arrangement.

I øvrigt er der mange (lokal)aviser som vist blot kopierer fotografens hukommelseskort ind som en fotoserie :-(

  • 0
  • 0
Michael Andersen

Hvis man i øvrigt arbejder på en kopi af billederne, så kan mogrify også bruges. mogrify er en del af ImageMagick og virker med samme argumenter som convert, men overskriver de eksisterende filer.


Hvis man ikke er interesseret i at overskrive eksisterende filer kan man bruge -path til mogrify:

mogrify -resize 1024 -path resized_img/ ./img/DSC_*.JPG

Så bliver output filerne smidt derhen.

  • 1
  • 0
Jens Sigersted

Til behandle RAW under Linux kan jeg anbefale Corel AfterShot Pro.
Jeg ved godt det ikke følger Linux filosofien da programmet er "closed-source" men det er et af de få programmer som retter sig til profesionelle arbejdsgange hvad billedbehandling angår.

Selv anvender jeg også convert hvis der skal skrives tekster på mange billeder.

  • 1
  • 0
Christian P. Broe Petersen

Yep. Jeg gør præcis det samme. Jeg var træt af, at mit fyr ind i mellem løb tør for træpiller, og jeg kan ikke høre hyletonen inde i huset. Desværre har det ikke noget interface, men jeg har sat en raspberry op med webcam, som snapper et billede af displayet, der viser temperaturen. Det kører jeg så imagemagik og tesseract på, og hvis temp er for lav, sender den en mail til en dertil indrettet mailbox, som min telefon checker. Den giver mig så en lille alarm, og jeg kan gå ud og fylde på, eller skrive til konen derhjemme, at fyret skal serviceres, hvis jeg ikke er hjemme.

  • 4
  • 0
Log ind eller Opret konto for at kommentere