Ja schon wieder ein Powershellscript. Ich bringe zur Zeit einige Internetseiten auf Vordermann und will dort optimal komprimierte Bilder hochladen. Am besten komprimiert werden Bilder auf tinypng.com aber ich wollte nicht immer auf die Internseite müssen. Darum habe ich ein Powershell Script geschrieben, das die API verwendet.
Man kann auf TinyPNG (oder TinyJPG) gehen und oben bei Developer API eine Emailadresse angeben. Dann kriegt man einen Link mit einem API Schlüssel zugeschickt, den man hierfür braucht.
Mit meinem Script kann man beliebig viele Jpg oder Png Bilder in einem Ordner haben. Dort kopiert man das Powershellscript hin, führt es aus und alle Bilder werden zuerst zu tinypng hochgeladen und dann die komprimierten Versionen heruntergeladen. Als nichtzahlender Kunde darf man so bis zu 500 Bilder im Monat komprimieren – für mich mehr als genug! Danach kostet ein Bild 0,009USD. Als normaler Blogger dürfte man aber nie so viel brauchen.
Das Maskottchen oben habe ich von der TinyPNG Website direkt per Screenshot geklaut und mit dem guten alten Paint zugeschnitten und abgespeichert. Man kann natürlich davon ausgehen, dass Paint nicht optimal abspeichert, daher habe ich das Bild direkt mit meinem Script komprimiert.
Wenn du eigentlich nur das Tool nutzen willst und dich gar nicht interessiert wie es programmiert ist, dann kannst du es auch hier herunterladen.
Zum Script:
$user = "api" $pass = "[dein API Key]" $pair = "${user}:${pass}" $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair) $base64 = [System.Convert]::ToBase64String($bytes) $basicAuthValue = "Basic $base64" $headers = @{ Authorization = $basicAuthValue } $regex = '"url":".*"' gci * -Include *.png, *.jpg | select -ExpandProperty name | %{ $return = Invoke-WebRequest -uri "https://api.tinify.com/shrink" -Headers $headers -InFile $_ -Method Post $url = Select-string -InputObject $return.Content -Pattern $regex -AllMatches | %{$_.Matches.Value.Replace('"url":"','').Replace('"','')} $output = "tinyfi" + $_ md -force tinyfi Invoke-WebRequest -Uri $url -OutFile $output }
Ich will auch wieder erklären was hier passiert.
Der ganze obere Teil ist nur zum Authentifizieren. Das ist ein bisschen blöd mit Powershell. Linuxbenutzer mit curl können da einfach –user schreiben. Mit Powershell muss man den Header leider selbst zusammenbauen. Den Teil kopiere ich aber auch einfach immer wieder (es ist der gleiche wie in meinem DynDNS mit Powershell Script).
gci: ist kurz für get-child-item und in Powershell das, was in Linux ls ist. Mit gci * sage ich, dass ich alle Dateien in einem Ordner aufgelistet haben will. Ich schränke das aber noch mit dem Parameter -Include ein. Der erlaubt mir mehr als ein Muster zu nehmen und so kann ich nach den zwei Endungen filtern die ich haben möchte. Gäbe es nur eine Mögliche Endung hätte z.b. gci *.jpg gereicht.
|: verkettet Befehle. Es wird die Ausgabe des vorigen Befehls in den neuen Befehl weitergeleitet.
select: ist ganz interessant. Das Ergebnis von gci * ist eine Tabelle und mit select kann man diese SQL artig weiterverarbeiten. Für die Ausgabe wäre gci * | select name optimal, allerdings will ich mit den Daten ja noch weiterarbeiten. Daher verwende ich den Parameter -ExpandProperty. Damit schneide ich letzendlich die Kopfzeile von der Tabelle weg.
| % {: die schicke kurze Variante für “Nimm jede einzelne Zeile von oben und mache mit ihr alles, was im Block bis zum Ende der geschweiften Klammer (})steht”
$return: Eine Variable, in der ich die Übergabe vom nächsten Befehl speichere, damit ich später damit weiterarbeiten kann.
Invoke-WebRequest: der curl von Powershell. Ich gebe mit -uri an, wo der Service liegt. -Headers beinhaltet den Authkram von weiter oben, auf den ich nicht eingehe, den wir aber brauchen.
-InFile $_: InFile heißt, dass eine Datei beim WebRequest mitgesendet wird. In diesem Fall ist der Pfad zur Datei in der Variable $_ und diese beinhaltet die Zeile, in der wir gerade wegen der %-Schleife sind. -Method Post ist die Übermittlungsart, die die API braucht.
$url: wieder eine Hilfsvariable. Das $return-Objekt beinhaltet alle möglichen Informationen, unter anderem unter welcher Url wir unser komprimiertes Bild finden. Die Wollen wir rausbekommen.
Select-String: Damit können wir einen Text durchsuchen. -InObject ermöglicht uns, in unserem eben erstellten $return zu suchen. -Pattern kann Regex beinhalten. Unser Regex hier ist weiter oben definiert.
“url”:”.*”: Bedeutet der Text den wir suchen sieht so aus: “url”:”[irgendwas]”
%{$_.Matches.Value.Replace: Wir schneiden vom Treffer alles ab bisauf die url selbst.
$output = “tinyfi” + $_: Hier basteln wir den Dateipfad für die neue Datei zusammen. Der Ordner “tinyfi” mit Dateinamen $_ (darin ist immer noch der Originalname aus der %-Schleife abgelegt).
md -force tinyfi: md erstellt ein Verzeichnis und -force verhindert in dem Fall nur den Fehler der kommt, wenn das Verzeichnis schon existiert. Beim Schreiben hier fällt mir dabei auf, dass es wenig elegant ist den md Befehl an dieser Stelle zu haben, weil das Progamm so versucht bei jedem Durchlauf den Ordner anzulegen und es natürlich reichen würde, wenn man das nur am Anfang einmal macht. Das ist nun deine Hausaufgabe!
Am Ende ist noch einmal ein Invoke-WebRequest, mit der Url, die wir weiter oben gebastelt haben und mit dem Pfad, den wir gebastelt haben. Das Ganze läuft in der %-Schleife für jeden Dateinamen in dem Ordner und am Ende hast du einen Ordner tinyfi, in dem alle deine Bilder liegen aber optimal komprimiert.
Womit komprimiert ihr eure Bilder?
Habt ihr schon mal die Powershell benutzt, um lästige Aufgaben zu vereinfachen?
2 Kommentare
Schreibe einen Kommentar →