Einfaches Imageresize + Caching
Ab und zu kummt's vor, dass a bereits existierendes Bild in ana ondern Größe braucht wird. Dann kann ma entweder mit Photoshop für jede Version vom Bild a individuell zugschnittene Version erstöin und diese in die Webseitn einbindn (do bietet si eventuell Autopush - Einfach gänderte Dateien hochlodn o), aber ma kann des Ganze a on-the-fly mit am PHP-Skript machn. Und um die Performance ned zu sehr leidn zu lassn, kann ma des Ganze a no cachen und somit nur dann des Originalbild zuschneidn, wenn's ned scho vorher auf die gwünschte Größe zugschnittn wurde. Des geht zwoar olles a bissl zu Lasten vom Speicherplatz, aber mit da manuellen Version (zuschneidn via Photoshop) wär des ja ned ondas ;-)
Mia brauchn dazu ois Erstes a .htaccess-Datei, de unsere .png-, .jpg- und .jpeg-Requests erstmoi an a PHP-Skript schickt, des dann die weitere Orbeit mocht. In die .htaccess-Datei kummt folgendes, damit mia bei jeder Bilddatei a automatisch des PHP-Skript durchlaufn:
RewriteRule ^(.*)\.(jpg|jpeg|png)/?([0-9]*)?/([0-9]*)?/?([0-1]{1})?$ parse_image.php?i=$1&e=$2&w=$3&h=$4&r=$5 [L,QSA]
Da Pfad zur parse_image.php muass natürlich ogepasst wern ;-) Diese HTACCESS-Regel mocht nix ondres, ois olle Dateien mit da Endung jpg, jpeg oda png abzufangen und an die parse_image.php weiterzuleitn. Weiterhin kinnan no 3 Parameter im Pfad-Stil angebn wern, de dann vom PHP-Skript valorbeit wern (siehe unten). Wenn koane Parameter übergebn wern, wird des "Hauptbild" aufgrufn, ohne weitere Veränderungen. De weiteren Parameter sand
- Bildbreite vom Ausgabebild (Parameter 1)
- Bildhöhe (Parameter 2)
- 1 oda 0, je nachdem, ob mia die Proportionen beibehoitn wolln oda ned (Parameter 3)
Aufrufn kinnan mia des Ganze dann folgendermaßen:
<img src="images/040.jpg/100/200/1">
images/040.jpg is da Pfad zum Bild, da erste Wert (100) is die Breite vom Ausgabebild, da zwoate (200) die Höhe, da dritte Wert gibt o, ob des Bild proportional skaliert wern soi oda ob einfach de gwünschte Stelle "ausgschnitten" wird. Do '1' - also wird die Ausgabe proportional skaliert. Des Skript zum Cachen bzw. zur Ausgabe schaut dann so aus: De Konstante "CACHEFOLDER" muass ogepasst wern, und zwoar auf an Ordner, auf den PHP Lese- und Schreibzugriff hot (sonst kunnatn mia des neiche Bild ja ned speichern). De Konstante ALLOWED_TYPES gibt ois klans Extra-Schmankerl no o, wöche Mime-Types zuglassn sand und wöche ned.
# Der Ordner, in dem wir die Bilder cachen
define("CACHEFOLDER", "cache/images/");
# Zugelassene Typen - hier jpeg, jpg und png
define("ALLOWED_TYPES", ['image/jpeg', 'image/jpg', 'image/png']);
# Wir beziehen die GET-Variable r (ratio) und speichern je nach dem ein true oder false in unserer $keep_ratio
$keep_ratio = ($_GET['r'] == '1') ? true : false;
# Es werden die GET-Parameter geholt und in Variablen geschrieben. Muss man natürlich nicht machen, macht den ganzen Vorgang aber übersichtlicher
list($file, $ext, $dimensions['w'], $dimensions['h']) = [$_GET['i'], $_GET['e'], isset($_GET['w']) ? $_GET['w'] : 0, isset($_GET['h']) ? $_GET['h'] : 0];
# Es wird ein MD5-Hash erstellt bestehend aus Dateiname, Zielbreite und Zielhöhe und der Information, ob die Dimensionen erhalten bleiben sollen oder nicht.
$hash = CACHEFOLDER . md5($file.$ext.$dimensions['w'].$dimensions['h'].(($keep_ratio) ? '1' : '0'));
# $file_src enthält den kompletten Pfad zur Originaldatei
$file_src = $file . '.' . $ext;
# Wenn die Originaldatei nicht von einem der o.g. ALLOWED_TYPES ist, brechen wir die Verarbeitung ab (es ist kein png, jpg oder jpeg Bild und höchstwahrscheinlich wurde das Skript direkt aufgerufen)
if (!in_array(mime_content_type($file_src), ALLOWED_TYPES)) die();
# Wenn keine Datei existiert, welche unserem Hash entspricht, dann gibt es keine gecachte Version unseres Bildes und wir erstellen eine.
# Hierzu erstellen wir erst ein jpeg Bild von unserem Originalbild, beziehen die Größe des Bildes und skalieren dann das Bild abhängig von den angegebenen Parametern
if (!file_exists($hash)){
$res['src'] = imagecreatefromjpeg($file_src);
$filedata = getimagesize($file_src);
if ($dimensions['w'] == 0 || $dimensions['h'] == 0) list($dimensions['w'], $dimensions['h']) = [$filedata[0], $filedata[1]];
$res['dst'] = imagecreatetruecolor($dimensions['w'], $dimensions['h']);
if ($keep_ratio === false){
imagecopyresized($res['dst'], $res['src'], 0, 0, 0, 0, $dimensions['w'], $dimensions['h'], $filedata[0], $filedata[1]);
}else{
if ($filedata[0] && $filedata[1]) {
$dst['h'] = $dimensions['h'];
$dst['w'] = floor($filedata[0] * ($dimensions['h'] / $filedata[1]));
$crop['x'] = ceil(($filedata[0] - $filedata[1]) / 2);
$crop['y'] = 0;
}else{
$dst['w'] = $dimensions['w'];
$dst['h'] = floor($filedata[1] * ($dimensions['w'] / $filedata[0]));
$crop['x'] = 0;
$crop['y'] = ceil(($filedata[1] - $filedata[0]) / 2);
}
imagecopyresampled($res['dst'], $res['src'], 0, 0, $crop['x'], $crop['y'], $dst['w'], $dst['h'], $filedata[0], $filedata[1]);
}
# Schlussendlich geben wir unsere Datei aus.
imagejpeg($res['dst'], $hash);
}
header('Content-Type: ' . mime_content_type($hash));
header('Content-Length: ' . filesize($hash));
readfile($hash);