Da es sehr gut funktioniert, möchte ich die fertige Ausführung hierzu noch reinstellen, wenn es jemand selbst mal versuchen möchte.
Vielleicht hat ja jemand noch Verbesserungsvorschläge, was den Algorithmus zur Bildverkleinerung anbelangt?
Die Ordnerstruktur:
Alle hochgeladenen Bilder liegen in Originalgröße in
/pics/pool/ und haben das Format 0000000001.jpg - 4294967295.jpg (MySQL Unsignend INT(10) Größe - für mich reicht das aus, sonst kann man auch Unsigned BigInt nehmen für bis zu 18446744073709551615 Bilder).
Die dynamisch verkleinerten Bilder werden vom Skript "getimage.php" abgelegt in
/pics/, ein Skript muss da also schreiben können.
Das Skript "getimage.php" liegt in
/php/tools/.
Die .htaccess liegt im Root-Verzeichnis
/.
Der Code
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^pics/([0-9]{10})\-(([1-9][0-9]*)|_)x(([1-9][0-9]*)|_)\.jpg$ ./php/tools/getimage.php?filename=$1&width=$2&height=$3 [L]
PHP-Skript "getimage.php"
<?php
function resizepicture($sourcefilename, $destfilename, $destwidth, $destheight) {
$sourceimage = imagecreatefromjpeg($sourcefilename);
list($sourcewidth, $sourceheight) = getimagesize($sourcefilename);
if ($destwidth == '_') $destwidth = $sourcewidth;
if ($destheight == '_') $destheight = $sourceheight;
if ($sourcewidth > $sourceheight) { //source is landscape format
if ($destheight / $destwidth > $sourceheight / $sourcewidth) {
$copyheight = $sourceheight;
$copywidth = floor($destwidth / $destheight * $copyheight);
} else {
$copywidth = $sourcewidth;
$copyheight = floor($destheight / $destwidth * $copywidth);
}
} else { //source is portrait or quadratic format
if ($destwidth / $destheight > $sourcewidth / $sourceheight) {
$copywidth = $sourcewidth;
$copyheight = floor($destheight / $destwidth * $copywidth);
} else {
$copyheight = $sourceheight;
$copywidth = floor($destwidth / $destheight * $copyheight);
}
}
$copyx = $copyy = 0;
if ($copyheight < $sourceheight) {
$copyy = floor(($sourceheight - $copyheight) / 2);
}
if ($copywidth < $sourcewidth) {
$copyx = floor(($sourcewidth - $copywidth) / 2);
}
$destimage = imagecreatetruecolor($destwidth, $destheight);
imagealphablending($destimage, false);
imagecopyresized($destimage, $sourceimage, 0, 0, $copyx, $copyy, $destwidth, $destheight, $copywidth, $copyheight);
@unlink($destfilename);
imagejpeg($destimage, $destfilename);
}
$filename = $_GET['filename'];
$width = $_GET['width'];
$height = $_GET['height'];
if (!preg_match('/^[0-9]{10}$/', $filename) ||
($width != '_' && !(int)$width) ||
($height != '_' && !(int)$height)) {
die('Bad parameters.');
}
$picturefilename = '../../pics/'.$filename.'-'.$width.'x'.$height.'.jpg';
if (!file_exists($picturefilename)) {
$sourcepicture = '../../pics/pool/'.$filename.'.jpg';
if (file_exists($sourcepicture)) {
resizepicture($sourcepicture, $picturefilename, $width, $height);
} else {
die('Picture not found!');
}
}
header('content-type: image/jpeg');
readfile('../../pics/'.$filename.'-'.$width.'x'.$height.'.jpg');
?>
Funktion
Um das nutzen zu können, reicht es einen einfachen Dateiupload für jpg-Dateien in den Ordner /pics/pool/ zu realisieren um die Bilder dort abzulegen und dafür zu sorgen, dass die Bilder ordnungsgemäß fortlaufend nummeriert werden. Ich habe das mit einer Tabelle gelöst, deren id Unsigned INT(10) / Autoincrement ist, und in dem immer ein Datensatz eingefügt wird, wenn ein Bild hochgeladen wird. Dort kann man dann auch Bildtitel, Text usw. ablegen, und die ID kann für den Bildnamen verwendet werden.
Wenn das Bild dort liegt, kann man nun von jeder Stelle aus einfach das Bild abrufen und die gewünschte Größe angeben:
<img src="/pics/0000000001-150x100.jpg" alt="" />
Verkleinert und schneidet das Bild auf das Format 150 Pixel Breite und 100 Pixel Höhe zu,
<img src="/pics/0000000001-150x_.jpg" alt="" />
Verkleinert das Bild auf die Breite 150 und lässt die Höhe proportional (Bild wird nicht geschnitten)
<img src="/pics/0000000001-_x200.jpg" alt="" />
Verkleinert das Bild auf 200 Pixel Höhe und die Breite bleibt proportional.
Man sollte sich aber von Anfang an bewusst sein, welche Bildgrößen man braucht, denn sonst hat man irgendwann sehr viele unnütze Bildgrößen in /pics/ liegen. Die muss man dann von Hand löschen. Der Vorteil des Systems liegt darin, dass man bei CMS-Modulen nicht noch herumfummeln muss, wenn man eine neue Seite / Modul hinzufügt, in der das Bildmaterial in anderer Größe gebraucht wird - man ruft es einfach auf und es steht so zur Verfügung.