Mit Hilfe von GDLib Thumbnails aus Bilderverzeichnis erstellen

Ron-da-Don

Grünschnabel
Ich bin gerade dabei mich mit der Problematik der serverseitigen Thumbnailerzeugung zu beschäftigen. Leider stoße ich immer wieder an meine Grenzen.

Ich würde gern, über ein Upload-Formular ein Bildverzeichnis auswählen können, welches dann per FTP auf den Server geladen wird. In diesem Verzeichnis soll dann auf dem Server ein Unterverzeichnis "thumbs" erstellt werden. Dummerweise weiß ich nur, wie ich einzelne Dateien auf einen Server lade, aber nicht eben komplette Verzeichnisse.

Somit habe ich mich erstmal mit der GDLib und der Thumbnailerstellung gekümmert. Ich habe bisher auf meinem Testserver ein Verzeichnis "000001" worin auch ein Unterverzeichnis "thumbs" ist.

Nun wollte ich folgendes Skript verwenden, um die bereits vorhandenen Bilder in Thumbnailgröße zu erstellen:
PHP:
<?php


header('Content-type: images/jpeg');

// Thumbnail-Verzeichnis
$dir = "000001/thumbs";

$imgsrc = imagecreatefromjpeg("../".$dir.$_REQUEST['dir']."/".$_request['img']);

// Breite und Höhe des Bildes ermitteln
$width = imagesx($imgsrc);
$height = imagesy($imgsrc);

// Neues Bild erstellen
$img = imagecreatetruecolor($width, $height);

// Bild in das Neuerstellte einfügen
imagecopy($img, $imgsrc, 0,0,0,0, $width, $height);

// Bild erstellen
imagejpeg($img);
imagedestroy($img);

?>
Leider funktioniert dieses Skript nicht, sondern der Broser denkt, ich möchte es herunterladen, wenn ich es aufrufe. Keine Sorge PHP ist auf dem Testserver installiert und die GDLib ebenfalls.

Weiß vielleicht jemand einen Rat und würde mir dabei behilflich sein. In einem anderen großen PHP-Forum wurde ich nur abgespeist mit Kommentaren wie "beschäftige dich mit PHP" oder "sollte eigentlich funktionieren".

Vielleicht stand ja selbst jemand vor dieser Problematik und kann mir einen Rat geben.

Gruß
Ron
 
Danke für die Antwort, aber den Header hatte ich fünf Minuten vor der Antwort auch geändert, also genau wie deine Antwort, jetzt passiert zwar etwas, aber es werden keine Thumbnails erstellt, sondern im Browserfenster steht nur die URL meiner Testdomain.
 
Nehme mal den Header komplett heraus und rufe dies Skript direkt im Browser auf(inklusive der zugehörigen Parameter)....du solltest, sofern es Fehler enthält, Hinweise darauf erhalten.
 
Den Header habe ich jetzt entfernt und nun kommen wenigstens Fehlermeldungen, aber gleich eine ganze Menge:
Warning: imagecreatefromjpeg() [function.imagecreatefromjpeg]: open_basedir restriction in effect. File(..//var/www/vhosts/xxx.de/subdomains/test/httpdocs/000001/thumbs//) is not within the allowed path(s): (/var/www/vhosts/xxx.de/subdomains/test/httpdocs:/tmp) in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 8

Warning: imagecreatefromjpeg(..//var/www/vhosts/xxx.de/subdomains/test/httpdocs/000001/thumbs//) [function.imagecreatefromjpeg]: failed to open stream: Operation not permitted in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 8

Warning: imagesx(): supplied argument is not a valid Image resource in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 11

Warning: imagesy(): supplied argument is not a valid Image resource in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 12

Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 15

Warning: imagecopy(): supplied argument is not a valid Image resource in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 18

Warning: imagejpeg(): supplied argument is not a valid Image resource in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 21

Warning: imagedestroy(): supplied argument is not a valid Image resource in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php on line 22

Klingt ja garnicht gut, also alle Verzeichnisse und Dateien habe ich schon auf "777" gesetzt, weil ich erst dachte, dass irgendwelche Rechte nicht stimmen.

Ich habe auch noch mal getestet, ob die GDLib drauf ist und das kam heraus:
PHP:
Array
(
    [GD Version] => 2.0 or higher
    [FreeType Support] => 1
    [FreeType Linkage] => with freetype
    [T1Lib Support] => 1
    [GIF Read Support] => 1
    [GIF Create Support] => 1
    [JPG Support] => 1
    [PNG Support] => 1
    [WBMP Support] => 1
    [XPM Support] => 
    [XBM Support] => 
    [JIS-mapped Japanese Font Support] => 
)

Also sollte technisch soweit alles stimmen.
 
Die Verarbeitung des Bildes wird bei mir so gelöst:
PHP:
function resizeImage($imgname, $tempname, $width, $height, $maxbh, $pfad){
	$quality = 85;
	$xfaktor = ($maxbh * 100) / $width;
	$yfaktor = ($maxbh * 100) / $height;
	if ($xfaktor < $yfaktor){
		$vbreite = $maxbh;
		$vhoehe = number_format((($height * $xfaktor) / 100), 0);
	}else{
		$vbreite = number_format((($width * $yfaktor) / 100), 0);
		$vhoehe = $maxbh;
	}
	$file_name_dest = "../$pfad/$imgname";
	$dest = imagecreatetruecolor($vbreite, $vhoehe);
	imageantialias($dest, TRUE);
	$src = imagecreatefromjpeg($tempname);
	imagecopyresampled($dest, $src, 0, 0, 0, 0, $vbreite, $vhoehe, $width, $height);
	imagejpeg($dest,$file_name_dest, $quality); 
   return TRUE; 
}
Das Script steht in einer eigenen Datei und wird so aufgerufen:
PHP:
$tempbild = getimagesize($_FILES['bild']['tmp_name']);
$xsize = $tempbild[0];
$ysize = $tempbild[1];
$tempname = $_FILES['bild']['tmp_name'];										

// Bei Timeout-Problemen den Wert erhöhen 
ini_set("max_execution_time", "3000"); 
include_once("../includes/vorschau.php");
$ret = resizeImage($name, $tempname, $xsize, $ysize, $maxbh, $pfad);
if (!$ret)
	exit ('<font color="red">Das Bild konnte nicht hochgeladen werden!');

Mit $maxbh kann eingestellt werden, wie groß die Vorschau gemacht werden soll.
Natürlich kann man die Größe der Vorlage auch später auslesen, nur wird bei mir vorher schon eine Mindestgröße ermittelt und dann übergebe ich die Werte gleich mit.
Wenn du dann das ganze noch in eine Schleife packst und das Verzeichnis durcharbeiten läßt, sollte der Großteil deines Problems erledigt sein. Der Upload eines ganzen Verzeichnisses in PHP ist meines Wissens nicht möglich. Ich hatte das Problem auch schon mal vor einiger Zeit und habe nur eine Lösung in Java gefunden, die aber auch nur sporadisch funktionierte. Solltest du da auf eine Lösung stoßen, sag Bescheid.
 
Zuletzt bearbeitet:
@Ron-Da-Don:

Das sieht schlimmer aus, als es ist.
Du versuchst nur, mit einem nicht erlaubten Pfad zu Arbeiten:

Code:
..//var/www/vhosts/xxx.de/subdomains/test/httpdocs/000001/thumbs//

Dein Verzeichnis lautet jedoch
Code:
/var/www/vhosts/xxx.de/subdomains/test/httpdocs

Alle anderen Fehlermeldungen werden dadurch verursacht, weil die Grafik nicht geöffnet werden kann.

Versuchs mal hiermit:
Code:
$imgsrc = imagecreatefromjpeg($_SERVER['DOCUMENT_ROOT']."/".$dir."/".$_REQUEST['dir']."/".$_request['img']);
 
@Sven

Vielen Dank für deine Idee, aber leider hat dies auch nicht zur Lösung beigetragen.
Nun wird mir wieder nur die Testdomain im Browserfenster angezeigt.

@Sprint
Ich habe deinen Ansatz einfach mal kopiert und habe den ersten Teil deines Quellcodes als index.php gespeichert und include die vorschau.php. Doch leider kommt wieder eine Fehlermeldung.
Fatal error: Cannot redeclare resizeimage() (previously declared in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/index.php:16) in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/vorschau.php on line 20

So langsam verzweifel ich. Ich habe schon Angst, das es nur an einer dämlichen Pfadangabe liegt. Aber wenn die inxe.php im Root-Verzeichnis liegt und auf das Verzeichnis "000001" und das darin liegende Verzeichnis "thumbs" zugreifen soll, dann lautet doch die Angabe:
PHP:
$dir = '000001/thumbs'
oder?
 
Wenn ich dich jetzt richtig verstanden habe, muß es genau umgekehrt sein. Der erste Teil mit der function gehört in die vorschau.php und der zweite in die index.
Die Fehlermeldung "Cannot redeclare resizeimage()" deutet für mich darauf hin, daß du zwei verschiedene Funktionen mit dem selben Namen belegst. Oder rufst du die in einer Schleife auf? Dann solltest du das include nach vorne setzen.
 
Hmm, also meine beiden Dateien sehen so aus.
index.php:
PHP:
<?php
$tempbild = getimagesize($_FILES['bild']['tmp_name']);
$xsize = $tempbild[0];
$ysize = $tempbild[1];
$tempname = $_FILES['bild']['tmp_name'];                                        

// Bei Timeout-Problemen den Wert erhöhen 
ini_set("max_execution_time", "3000"); 
include_once('vorschau.php');
$ret = resizeImage($name, $tempname, $xsize, $ysize, $maxbh, $pfad);
if (!$ret)
    exit ('<font color="red">Das Bild konnte nicht hochgeladen werden!');  
?>

vorschau.php
PHP:
<?php
function resizeImage($imgname, $tempname, $width, $height, $maxbh, $pfad){
    $quality = 85;
    $xfaktor = ($maxbh * 100) / $width;
    $yfaktor = ($maxbh * 100) / $height;
    if ($xfaktor < $yfaktor){
        $vbreite = $maxbh;
        $vhoehe = number_format((($height * $xfaktor) / 100), 0);
    }else{
        $vbreite = number_format((($width * $yfaktor) / 100), 0);
        $vhoehe = $maxbh;
    }
    $file_name_dest = "000001/thumbs";
    $dest = imagecreatetruecolor($vbreite, $vhoehe);
    imageantialias($dest, TRUE);
    $src = imagecreatefromjpeg($tempname);
    imagecopyresampled($dest, $src, 0, 0, 0, 0, $vbreite, $vhoehe, $width, $height);
    imagejpeg($dest,$file_name_dest, $quality); 
    return TRUE; 
}
?>

Jetzt kommt folgende Fehlermeldung:
Warning: Division by zero in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/vorschau.php on line 4

Warning: Division by zero in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/vorschau.php on line 5

Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/vorschau.php on line 14

Fatal error: Call to undefined function imageantialias() in /var/www/vhosts/xxx.de/subdomains/test/httpdocs/vorschau.php on line 15

Das sieht ja schon nicht mehr ganz so tragisch aus.
 
Zurück