Navigation Logo der Webseite

Responsive Images — Erstellung

Veröffentlicht am von in Querbeet

Für eine Webseite ist es sinnvoll, dass Bilder in verschiedenen Auflösungen bereitgestellt werden, um die Nutzererfahrung so positiv wie möglich zu gestalten. Kleine Anzeige, kleines Bild laden, große Anzeige, großes Bild laden. Gerade für mobile Nutzer ist es wieder wichtig, auf die Gesamt-Download-Größe der Seite zu achten und Bilder haben daran nun mal den größten Anteil.

Hier nun meine Art, diese Bilder möglichst bequem zu generieren.

Rahmenbedingungen

Ich arbeite auf einem System mit Windows 10 und habe von meinem Vorgehen nach Foto-Touren einen Ordner mit aus Lightroom exportierten Fotos im JPEG-Format. Sie haben je nach Beschnitt völlig unterschiedliche Größen und liegen im Hoch- oder Querformat vor.

Das Ziel

Im Explorer markierte Objekte (Ordner oder Dateien) sollen über das Kontextmenü mit „Senden an“ zu einem Skript gereicht werden, welches dann alle *.jp(e)g-Dateien in die angegebenen Größen konvertiert. Dabei wird nur die Breite vorgegeben, die Höhe passt sich so an, dass das Seitenverhältnis beibehalten wird.

Der eigentliche Vorgang der Konvertierung wird mit imageMagick bzw. dessen Tool convert durchgeführt. Bei einem Seitenverhältnis von 3 : 2 sind folgende Auflösungen gewünscht: 1200 × 795, 800 × 530 und 400 × 265. Dabei ist darauf zu achten, dass die Bilder im Hoch- bzw. Querformat bleiben.

Das Programm

Für Ungeduldige gibt es hier eine Abkürzung zum Download.

Parameter sortieren

Da über das „Senden an“-Menü sowohl Ordner als auch Dateien geschickt werden können, müssen wir gleich zu Beginn die erste Kontrolle einbauen (und die erste Einschränkung hinnehmen). Liegt ein Ordner oder ein Bild vor? Entscheidend ist hierbei ausschließlich der erste Parameter, der übergeben wird. Bei gemischten Angaben werden beim Durchlauf des Skripts Fehler (wegen falschen Aufrufs von imageMagick) ausgegeben.

Der Funktion :MKRESDIR zum Anlegen eines neuen, eindeutigen Ordners für die konvertierten Bilder wird mit dem aktuellen Pfad des Bildes (%~dp1) aufgerufen.

Das Konstrukt :LOOP, …, SHIFT, goto :LOOP sorgt dafür, dass alles dazwischen stehende nacheinander für jeden Parameter (jede/r Datei/Ordner) durchgeführt wird. Ist der letzte Parameter verarbeitet, schlägt die erste Kontrolle an und wir springen zum Ende der Datei mit goto :END.

Im sich wiederholenden Block wird mit %~x1 die Dateiendung auf Gleichheit mit JP(E)G geprüft, mit %~dp1 der Pfad des Bildes gesetzt und die Funktion :DECIDE mit dem kompletten Dateinamen (%~nx1) aufgerufen.

 1if not exist %1\NUL (
 2	call :MKRESDIR %~dp1
 3	:LOOP
 4	if "%1" == "" (
 5		goto :END
 6	)
 7	if "%~x1" == ".jpg"  (
 8		set pathnow=%~dp1
 9		call :DECIDE %~nx1
10	)
11	if "%~x1" == ".jpeg"  (
12		set pathnow=%~dp1
13		call :DECIDE %~nx1
14	)
15	SHIFT
16	goto :LOOP
17)
Codeabschnitt 1 Parameter sind Pfade zu Dateien

Sind Ordnerpfade bei der Batch-Datei angekommen, kümmert sich der folgende Code darum, dass für jedes JP(E)G im Ordner die Funktion :DECIDE aufgerufen wird. Die eingesetzte for-Schleife generiert mit dem dir-Befehl zunächst eine Liste aller Dateien mit der Endung .jp*g und arbeitet diese Liste dann ab.

 1 else (
 2	:LOOP2
 3	if "%1" == "" (
 4		goto :END
 5	)
 6	set pathnow=%1
 7	call :MKRESDIR %1
 8	for /f %%f in ('dir /b %1\*.jp*g') do (
 9		call :DECIDE %%f
10	)
11	SHIFT
12	goto :LOOP2
13)
14goto :END
Codeabschnitt 2 Parameter sind Ordnerpfade

Damit sind alle Parameter verarbeitet, geht es mit goto :END an die entsprechende Sprungmarke am Ende der Datei.

Was machen aber nun die Funktionen? Werfen wir einen Blick darauf!

Ordner anlegen

Versuchen wir es zunächst mit einem Standard-Namen (hier resize) für den Ziel-Ordner. Existiert ein solcher Ordner bereits, erstellen wir einen anderen Ordner, der über die aktuelle Zeit einen eindeutigen Namen hat (und damit noch nicht existieren sollte): resize-HH-MM-SS.

Für den Fall, dass auch dieser Ordner schon existieren sollte, wird er dennoch verwendet und ggf. vorhandene Dateien überschrieben. Mit der letzten Zeile goto :EOF geht es zurück an die Stelle, welche die Funktion aufgerufen hat.

1:MKRESDIR
2	if not exist "%1\resize" (
3		mkdir %1\resize
4		set resdir=resize
5	) else (
6		set resdir=resize-%time:~0,2%_%time:~3,2%_%time:~6,2%
7		mkdir %1\!resdir!
8	)
9	goto :EOF
Codeabschnitt 3 Lege einen eindeutigen Ordner für die neuen Bilder an

Die Entscheidung

Jetzt informieren wir den Nutzer darüber, welche Datei gerade bearbeitet wird und setzen zwei Variablen, die Höhe und die Breite des Bildes in Pixeln. Die lange Konstruktion ist notwendig, da ein einfaches set height=indentify... nicht funktioniert - Batch ist alt!

Wenn die Höhe geringer oder gleich der Breite ist, handelt es sich um ein Bild im Querformat (engl. landscape), sonst um ein Hochformat (engl. portrait). Je nachdem, welche Format vorliegt, wird die Funktion :CONIMGS dreimal mit den entsprechenden Parametern aufgerufen. Zuerst der Pfad, dann die Breite der Ausgabe in Pixeln und dann das an den Dateinamen angehängte Suffix.

 1:DECIDE
 2	echo Working on file %1...
 3	for /f "delims=" %%a in ('identify -format %%h %pathnow%\%1') do @set height=%%a
 4	for /f "delims=" %%a in ('identify -format %%w %pathnow%\%1') do @set width=%%a
 5	if !height! LEQ !width! (
 6		call :CONIMGS %pathnow%\%1 %landsmall% small
 7		call :CONIMGS %pathnow%\%1 %landmedium% medium
 8		call :CONIMGS %pathnow%\%1 %landlarge% large
 9		echo.
10	) else (
11		call :CONIMGS %pathnow%\%1 %portsmall% small
12		call :CONIMGS %pathnow%\%1 %portmedium% medium
13		call :CONIMGS %pathnow%\%1 %portlarge% large
14		echo.
15	)
16	goto :EOF
Codeabschnitt 4 Die Entscheidung über das Format

Nach dem dreimaligen Aufruf wird mit echo. ein Zeilenumbruch in der Ausgabe erzeugt.

Aufruf von imageMagick

Beim Aufruf der Funktion :CONIMGS wird der Nutzer darüber informiert, welche Auflösung gerade gerendert wird und welches Suffix die Datei erhalten wird. Mit dem Konstrukt echo|set /p d=TEXT wird der Text ohne abschließenden Zeilenumbruch ausgegeben.

Anschließend wird der convert-Befehl von imageMagick aufgerufen. Ein wesentlich kürzerer Aufruf wäre möglich mit convert INPUTFILE -thumbnail BREITE OUTPUTFILE, die hinzugefügten Bilder sorgen jedoch für eine minimale Dateigröße, was ja unter anderem ein Grund für dieses ganze Skript ist — wer will schon mehrere 5 MB große Bilder für einen Artikel laden?

1:CONIMGS
2	echo|set /p dummy=%2 (%3) px...
3	convert %1 -filter Triangle -define filter:support=2 -thumbnail %2 -unsharp 0.25x0.08+8.3+0.045 -dither None -posterize 136 -quality 82 -define jpeg:fancy-upsampling=off -define png:compression-filter=5 -define png:compression-level=9 -define png:compression-strategy=1 -interlace none -colorspace sRGB %~dp1%resdir%\%~n1-%3%~x1
4	goto :EOF
Codeabschnitt 4 Der Aufruf von convert

Meta-Daten

Die Option -thumbnail sorgt dafür, dass auch sämtliche Meta-Daten (z. B. EXIF und IPTC) der Bilder entfernt werden. Für Vorschauen sind diese Daten auch unnötig. Möchte man diese Daten aber behalten, weil man dem interessierten Betrachter die Möglichkeit geben will sie zu studieren, so ersetze -thumbnail mit -resize — weitere Änderungen sind nicht nötig. Die Dateien sind dann jedoch nach meinen Erfahrung bis zu 30 KB größer als vorher.

Der Code, komplett

Nachdem mit den Code-Schnipseln von oben noch immer einiges an Copy & Paste-Arbeit zu erledigen wäre, hier das komplette Skript zum Download. Es wird ein eindeutiger Unterordner angelegt, dorthin werden die Bilder konvertiert und mit der Namenserweiterung -small (400/265 Pixel), -medium (800/530 Pixel) bzw. -large (1200/795 Pixel) angelegt.

Einbau in das Kontextmenü

Speichere eine oder beide Skripte an einem geeignet erscheinenden Ort und lege jeweils eine Verknüpfung an. Wähle den Namen der Verknüpfung mit Bedacht — das ist der angezeigte Eintrag im „Senden an“-Menü. Dazu öffne ein Explorer-Fenster und gib in die Adresszeile shell:sendto ein und bestätige mit Enter. Kopiere die Verknüpfung(en) in den sich öffnenden Ordner. Fertig.

Quellen

Auf die Parameter zum Aufruf von imageMagick bin ich nicht selbst gekommen, das smashingmagazine hat da hervorragende Vorarbeit geleistet und verdammt viele Parameter durchprobiert und die Ergebnisse verglichen.

Viel Erfolg beim nachmachen!