Erstellung von Thumbnails klappt nicht
Enrico
- php
0 ChrisB0 Gunnar Bittersmann0 Der Martin0 Neuer Anlauf
Enrico0 Matthias Apsel0 Tom
0 mea culpa
Enrico
Hallo,
ich versuche, mittels PHP kleine Vorschaubilder zu erstellen, um diese nicht manuell verkleinern und abspeichern (und so wertvollen Speicherplatz vergeuden) zu müssen.
In meiner PHP-Datei will ich die zu verkleinernden Grafiken wie folgt einbinden:
<img src="../PHP/Verkleinern.php?Bild=' . $Bild . '&NeueHoehe=95">
Die Variable "Bild" wird vor der Übergabe natürlich belegt.
Die Datei Verkleinern.php hat folgenden Aufbau:
<?php
if (isset ($_GET['Bild']))
{
if (isset ($_GET['NeueHoehe']))
{
$NeueHoehe = $_GET['NeueHoehe'];
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
$Bildgroesse = getimagesize($Bild);
$Breite = $Bildgroesse[0];
$Hoehe = $Bildgroesse[1];
$Faktor = $NeueHoehe / $Hoehe;
$BreiteThumb = $Breite * $Faktor;
$HoeheThumb = $Hoehe * $Faktor;
$Thumbnail = imagecreatetruecolor($BreiteThumb, $HoeheThumb);
$Bild = imagecreatefrompng($Bild);
imagecopyresampled($Thumbnail, $Bild, 0, 0, 0, 0, $BreiteThumbnail, $HoeheThumbnail, $Breite, $Hoehe);
header('Content-Type: image/png');
imagepng($Thumb);
imagedestroy($Thumb);
}
else
{
echo 'Die Variable "NeueHoehe" wurde nicht übergeben';
}
}
else
{
echo 'Die Variable "Bild" wurde nicht übergeben';
}
?>
Die zu erzeugende Grafik wird aber weder angezeigt noch erhalte ich (eine) Warn- oder Fehlermeldung(en).
Die Anzeige von Warnungen und Fehlermeldungen habe ich aktiviert:
error_reporting(E_ALL|E_STRICT);
ini_set('display_errors', 1);
Der Quelltext liefert mir für den img-Tag folgenden Code:
<img src="../PHP/Verkleinern.php?Bild=GewandungMuetzen1&NeueHoehe=95">
Wo liegt/liegen der/die Fehler bei meiner Vorgehensweise?
Gut, die obige Variable "Faktor" sollte ich noch ggfs. runden, aber daran dürfte es wohl nicht liegen.
Braucht ihr ggfs. noch weitere Angaben, um mir helfen zu können?
Vielen Dank im Voraus für eure Hilfe und Gruß,
Enrico
Hi,
Die zu erzeugende Grafik wird aber weder angezeigt noch erhalte ich (eine) Warn- oder Fehlermeldung(en).
Wie soll denn bitte der Browser Fehlermeldungen darstellen koennen, wenn du das ganze per <img> einbindest?
Der Quelltext liefert mir für den img-Tag folgenden Code:
<img src="../PHP/Verkleinern.php?Bild=GewandungMuetzen1&NeueHoehe=95">
Dann ruf diese URL direkt in deinem Browser auf.
Und wenn das noch nichts bringt, dann kommentiere den Content-Type Header im Script aus.
> Wo liegt/liegen der/die Fehler bei meiner Vorgehensweise?
Du scheinst immer noch recht wenig Plan zu haben, wie man beim Debuggen \*logisch\* vorgeht.
MfG ChrisB
--
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
@@Enrico:
nuqneH
<img src="../PHP/Verkleinern.php?Bild=' . $Bild . '&NeueHoehe=95">
BTW: Wenn du URIs mit in den HTML-Kontext bringst, musst du das '&' entsprechen escapen.
Qapla'
Hi,
$Thumbnail = imagecreatetruecolor($BreiteThumb, $HoeheThumb);
$Bild = imagecreatefrompng($Bild);
imagecopyresampled($Thumbnail, $Bild, 0, 0, 0, 0, $BreiteThumbnail, $HoeheThumbnail, $Breite, $Hoehe);
header('Content-Type: image/png');
imagepng($Thumb);
imagedestroy($Thumb);
fällt dir nichts auf? Wäre ich PHP, würde ich an der Stelle quengeln, dass mir $Thumb nicht bekannt ist.
Die zu erzeugende Grafik wird aber weder angezeigt noch erhalte ich (eine) Warn- oder Fehlermeldung(en).
Das halte ich für ein Gerücht. Nur in Bilddaten eingebettet erkennst du sie vielleicht nicht. Wenn du die Ausgabe des Scripts aber erstmal in Textform betrachtest, dann schon.
Und ja, ich schließe mich Chris an: Du solltest dein logisches Denken und Vorgehen trainieren.
Ciao,
Martin
Hallo,
danke für eure Antworten.
Ich habe jetzt den Code überarbeitet und mich dabei an dieser Seite orientiert.
Die Seite "Verkleinern.php" hat jetzt folgenen Aufbau:
<?php
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
$Bild = imagecreatefrompng($Bild);
$UrspruenglicheBreite = imagesx($Bild);
$UrspruenglicheHoehe = imagesy($Bild);
if (isset ($_GET['Breite']))
{
$NeueBreite = $_GET['Breite'];
$NeueHoehe = round($UrspruenglicheHoehe / ($UrspruenglicheBreite / $NeueBreite));
$NeueBreite = round($UrspruenglicheBreite / ($UrspruenglicheHoehe / $NeueHoehe));
}
if (isset ($_GET['Hoehe']))
{
$NeueHoehe = $_GET['Hoehe'];
$NeueBreite = round($UrspruenglicheBreite / ($UrspruenglicheHoehe / $NeueHoehe));
$NeueHoehe = round($UrspruenglicheHoehe / ($UrspruenglicheBreite / $NeueBreite));
}
if(!$Thumbnail = imagecreatetruecolor($NeueBreite, $NeueHoehe))
{
$Thumbnail = imagecreate($NeueBreite, $NeueHoehe);
}
if(!$Thumbnail = imagecopyresampled($Thumbnail, $Bild, 0, 0, 0, 0, $NeueBreite, $NeueHoehe, $UrspruenglicheBreite, $UrspruenglicheHoehe))
{
imagecopyresized($Thumbnail, $Bild, 0, 0, 0, 0, $NeueBreite, $NeueHoehe, $UrspruenglicheBreite, $UrspruenglicheHoehe);
}
$Bild = $Thumbnail;
// header("Content-type:image/png");
imagepng($Bild, "", 9);
?>
Der Code zum Einbinden der zu verkleinernden Grafiken sieht wie folgt aus:
echo '<img src="Verkleinern.php?Bild=' . $Bild . '.png&Hoehe=95">';
Das "&"-Zeichen habe ich, wie es Gunnar geschrieben hatte, nun escaped.
Ein Blick in den erzeugten Quelltext liefert mir folgende Ausgabe:
<img src="Verkleinern.php?Bild=GewandungMuetzen1&Hoehe=95">
<img src="Verkleinern.php?Bild=GewandungMuetzen2&Hoehe=95">
Wenn ich, wie es mir Chris geraten hat, die URL direkt im Browser aufzurufen, bekomme ich folgende Meldungen:
Notice: Undefined variable: NeueBreite in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 25
Notice: Undefined variable: NeueHoehe in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 25
Warning: imagecreatetruecolor() [function.imagecreatetruecolor]: Invalid image dimensions in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 25
Notice: Undefined variable: NeueBreite in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 27
Notice: Undefined variable: NeueHoehe in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 27
Warning: imagecreate() [function.imagecreate]: Invalid image dimensions in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 27
Notice: Undefined variable: NeueBreite in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 30
Notice: Undefined variable: NeueHoehe in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 30
Warning: imagecopyresampled() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 30
Notice: Undefined variable: NeueBreite in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 32
Notice: Undefined variable: NeueHoehe in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 32
Warning: imagecopyresized() expects parameter 1 to be resource, null given in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 32
Warning: imagepng() expects parameter 1 to be resource, null given in C:\xampp\htdocs\WEBSHOP\PHP\Verkleinern.php on line 39
Wenn ich das jetzt zerlege, dann wird scheinbar der Parameter "Hoehe" entweder nicht übergeben oder nicht (richtig) eingelesen, denn alle anderen Anweisungen bauen ja auf diesem Wert auf.
Warum wird der Wert nicht übergeben oder nicht (richtig) eingelesen?
Hängt das damit zusammen, dass der Wert nicht als Zahl interpretiert wird?
Gruß,
Enrico
Om nah hoo pez nyeetz, Enrico!
ein Umkopieren der Werte ist nicht notwendig.
Du solltest auch prüfen, ob in $_GET['Bild'] was sinnvolles steckt.
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
$Bild = imagecreatefrompng($Bild);
$faktor = 1;
if (isset ($_GET['Breite'])) {
if (intval($_GET['Breite']) >= 100) {
$faktor = intval($_GET['Breite'])/imagesx($Bild);
}
else {
$faktor = 100/imagesx($Bild);
}
elseif (isset ($_GET['Hoehe'])) {
if (intval($_GET['Hoehe']) >= 100) {
$faktor = intval($_GET['Hoehe'])/imagesy($Bild);
}
else {
$faktor = 100/imagesy($Bild);
}
}
$NeueHoehe = round(imagesx($Bild) * $faktor);
$NeueBreite = round(imagesy($Bild) * $faktor);
Wenn nichts eingegeben wird, soll das Bild so bleiben, also Faktor = 1.
Du möchtest sicher nicht alle möglichen Werte zulassen. So solltest du sicherstellen, dass ein bestimmtes Maß nicht unterschritten wird. (Im Beispiel 100)
Außerdem soll das Bild sicher nicht verzerrt werden, wenn doch, musst du einen einzelnen Streckungsfaktor für die Höhe und einen für die Breite haben.
Eine maximale Höhe wäre sicher auch toll.
Platzsparend würde ich den ternären Operator verwenden.
Matthias
Hello Enrico,
mach da doch mal vernünftig abgegrenzte Funktionen draus.
z. B.:
Funktion "get_new_dims()" beschafft die Parameter aus der URL und berechnet daraus die neuen Dimensionen des Bildes.
Funktion "create_thumb()" beschafft dann das Orioginalbild, macht daraus eine Speicherdarstellung _in__der__vollen__Größe_ und wandelt diese dann entsprechend der übergebenen neuen Daten um in das Miniaturbild.
Und wenn die Funktionen entweder Daten (z. B. als Array) oder false zurückgeben, dann kannst Du auch vernünftig eingrenzen, ab welcher Stelle das Programm nicht mehr das tut, was Du dir vorgestellt hast.
Fehlerbehandlung hast Du nämlich bsiher überhaupt nicht drin.
Die muss aber dringend eingebaut werden.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo Tom,
ok, Deinen Vorschlag beherzigt und (in jetzt wesentlich längerem Code) umgesetzt:
<?php
ParameterHolen();
function ParameterHolen()
{
if (isset ($_GET['Bild']))
{
if ($_GET['Bild'] != "")
{
if (preg_match ("/^[A-Za-z\d{1,}]*$/", $_GET['Bild']))
{
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
if (isset ($_GET['Breite']))
{
if ($_GET['Breite'] != "")
{
if (preg_match ("/^\d{1,}$/", $_GET['Breite']))
{
GroesseBerechnen($Bild, $_GET['Breite'], "");
}
else
{
echo 'Der Parameter "Breite" ist ungültig';
}
}
else
{
echo 'Der Parameter "Breite" ist leer';
}
}
else
if (isset ($_GET['Hoehe']))
{
if ($_GET['Hoehe'] != "")
{
if (preg_match ("/^\d{1,}$/", $_GET['Hoehe']))
{
GroesseBerechnen($Bild, "", $_GET['Hoehe']);
}
else
{
echo 'Der Parameter "Hoehe" ist ungültig';
}
}
else
{
echo 'Der Parameter "Hoehe" ist leer';
}
}
else
{
echo "Breiten- oder Höhenangabe fehlt";
}
}
else
{
echo 'Der Parameter "Bild" ist ungültig';
}
}
else
{
echo 'Der Parameter "Bild" ist leer';
}
}
else
{
echo 'Der Parameter "Bild" wurde nicht übergeben';
}
}
function GroesseBerechnen($Bild, $NeueBreite, $NeueHoehe)
{
$UrspruenglicheGroesse = getimagesize($Bild);
$UrspruenglicheBreite = $UrspruenglicheGroesse[0];
$UrspruenglicheHoehe = $UrspruenglicheGroesse[1];
echo "Ursprüngliche Größe: " . $UrspruenglicheBreite . "x" . $UrspruenglicheHoehe . "<br>";
if ($NeueBreite != "")
{
$NeueHoehe = round($UrspruenglicheHoehe / ($UrspruenglicheBreite / $NeueBreite));
$NeueBreite = round($UrspruenglicheBreite / ($UrspruenglicheHoehe / $NeueHoehe));
BildErzeugen($Bild, $UrspruenglicheBreite, $UrspruenglicheHoehe, $NeueBreite, $NeueHoehe);
}
else
if ($NeueHoehe != "")
{
$NeueBreite = round($UrspruenglicheBreite / ($UrspruenglicheHoehe / $NeueHoehe));
$NeueHoehe = round($UrspruenglicheHoehe / ($UrspruenglicheBreite / $NeueBreite));
BildErzeugen($Bild, $UrspruenglicheBreite, $UrspruenglicheHoehe, $NeueBreite, $NeueHoehe);
}
}
function BildErzeugen($Bild, $UrspruenglicheBreite, $UrspruenglicheHoehe, $NeueBreite, $NeueHoehe)
{
$Bild = imagecreatefrompng($Bild);
if (!$Thumbnail = imagecreatetruecolor($NeueBreite, $NeueHoehe))
{
$Thumbnail = imagecreate($NeueBreite, $NeueHoehe);
}
if (!$Thumbnail = imagecopyresampled($Thumbnail, $Bild, 0, 0, 0, 0, $NeueBreite, $NeueHoehe, $UrspruenglicheBreite, $UrspruenglicheHoehe))
{
imagecopyresized($Thumbnail, $Bild, 0, 0, 0, 0, $NeueBreite, $NeueHoehe, $UrspruenglicheBreite, $UrspruenglicheHoehe);
}
// header("Content-type:image/png");
imagepng($Thumbnail, "", 9);
}
Jetzt erhalte ich "nur" noch folgende Meldung:
Warning: imagepng() expects parameter 1 to be resource, boolean given
Der Rest paßt so oder gibt es noch etwas zu verbessern/korrigieren?
Ich werde, wenn alles 100% funktioniert, ternäre Operator verwenden, so wie es Matthias vorgeschlagen hat, aber jetzt macht es wenig Sinn, falls sich irgendwo vorher noch ein Fehler versteckt haben sollte (die testweisen echo-Ausgaben in den einzelnen Funktionen liefern bis zur letzten Funktion "BildErzeugen" die gewünschten Werte).
Gruß,
Enrico
Tach!
if (isset ($_GET['Bild']))
{
if ($_GET['Bild'] != "")
{
Das kann man zusammenfassen. empty() erzeugt auch keine Notice, wenn man nicht vorhandene Werte damit prüft.
if (preg_match ("/[1]*$/", $_GET['Bild']))
{
Andererseits kannst du das isset() auch allein stehen lassen, denn der RegExp prüft ja ebenfalls auf nicht leere Werte, wenn man es richtig macht. + steht für 1 oder mehrere, * beinhaltet auch 0. Innerhalb einer [Zeichenklasse] sind Multiplikatoren sinnlos, weil eine Zeichenklasse immer nur für ein Zeichen steht. Multiplikatoren können nur dahinter stehen. Und so sind {1,} nichts besonderes, jedes Zeichen steht hier für sich selbst.
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
Jetzt wäre sinnvoll, zu prüfen ob $Bild überhaupt auf eine Bild-Datei verweist. Anderenfalls braucht es die Prüfungen der anderen Parameter nicht.
if (isset ($_GET['Breite']))
{
if ($_GET['Breite'] != "")
{
if (preg_match ("/^\d{1,}$/", $_GET['Breite']))
{
!empty() und is_numeric() in einem if würde auch reichen. Du musst nur wissen, ob da eine Zahl drin ist, dann rechnen. Ansonsten auf gleiche Weise die Zahl im Höhenparameter suchen, und wenn da auch ncihts ist, dann reicht eine gemeinsame Fehlermeldung.
function GroesseBerechnen($Bild, $NeueBreite, $NeueHoehe)
{
$UrspruenglicheGroesse = getimagesize($Bild);
Jetzt wäre eine Prüfung angebracht, dass getimagesize() nicht false zurückgegeben hat.
$UrspruenglicheBreite = $UrspruenglicheGroesse[0];
$UrspruenglicheHoehe = $UrspruenglicheGroesse[1];
Mach es die nicht zu schwer mit den Variablennamen. Das musst du alles tippen und man muss es lesen. $x und $y sind schneller, für beides. $newX und $newY würde ich die anderen benennen.
if (!$Thumbnail = imagecopyresampled($Thumbnail, $Bild, 0, 0, 0, 0, $NeueBreite, $NeueHoehe, $UrspruenglicheBreite, $UrspruenglicheHoehe))
imagepng($Thumbnail, "", 9);
Warning: imagepng() expects parameter 1 to be resource, boolean given
Ja, imagecopyresampled() gibt einen Boolean-Wert zurück. Den solltest du lieber direkt prüfen, statt ihn in $Tumbnail zu stecken, was eigentlich deine Variable für die Bildressource ist.
dedlfix.
A-Za-z\d{1,} ↩︎
Hallo dedlfix,
mit nachfolgendem Code funktioniert nun zumindest schonmal die direkte Ausgabe im Browser per Eingabe in der Adressleiste mittels Verkleinern.php?Bild=GewandungMuetzen1&Hoehe=95:
<?php
ParameterHolen();
function ParameterHolen ()
{
if (isset ($_GET['Bild']) && $_GET['Bild'] !== "")
{
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
if (file_exists ($Bild))
{
if (isset ($_GET['Breite']) && $_GET['Breite'] !== "")
{
if (is_numeric ($_GET['Breite']))
GroesseBerechnen ($Bild, $_GET['Breite'], "");
else
echo 'Die Variable "Breite" ist keine Zahl';
}
else
if (isset ($_GET['Hoehe']) && $_GET['Hoehe'] !== "")
{
if (is_numeric ($_GET['Hoehe']))
GroesseBerechnen ($Bild, "", $_GET['Hoehe']);
else
echo 'Die Variable "Hoehe" ist keine Zahl';
}
else
echo 'Funktion "ParameterHolen": Breiten- oder Höhenangabe fehlt';
}
else
echo 'Die Datei "' . $Bild . '" konnte nicht gefunden werden';
}
else
echo 'Die Variable "Bild" besteht nicht oder ist leer';
}
function GroesseBerechnen ($Bild, $xNeu, $yNeu)
{
if ($Groesse = getimagesize ($Bild))
{
$x = $Groesse[0];
$y = $Groesse[1];
if ($xNeu != "")
{
$yNeu = round ($y / ($x / $xNeu));
$xNeu = round ($x / ($y / $yNeu));
BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu);
}
else
if ($yNeu != "")
{
$xNeu = round ($x / ($y / $yNeu));
$yNeu = round ($y / ($x / $xNeu));
BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu);
}
else
echo 'Funktion "GroesseBerechnen": Breiten- oder Höhenangabe fehlt';
}
else
echo 'Funktion "GroesseBerechnen": "getimagesize" ist fehlgeschlagen';
}
function BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu)
{
$Bild = imagecreatefrompng ($Bild);
if (! $Thumbnail = imagecreatetruecolor ($xNeu, $yNeu))
$Thumbnail = ImageCreate($xNeu,$yNeu);
if (! imagecopyresampled ($Thumbnail, $Bild, 0, 0, 0, 0, $xNeu, $yNeu, $x, $y))
imagecopyresized ($Thumbnail, $Bild, 0, 0, 0, 0, $xNeu, $yNeu, $x, $y);
$Bild = $Thumbnail;
header("Content-type:image/png");
imagepng ($Bild, "", 9);
}
?>
Gut, die Grafik wird noch auf schwarzem Hintergrund und nicht transparent dargestellt, was ich noch lösen muss, aber die verkleinerte Anzeige klappt zumindest schon mal.
Ist das mit dem Erhalt der vormaligen Transparenz kompliziert?
Nebenbei: wenn ich, so wie Chris es vorgeschlagen hatte, das "&" escape und statt dessen "&" schreibe, dann läuft mir das Skript bei der Abfrage nach Breite und Höhe in den finalen else-Zweig und spuckt mir meine Fehlermeldung aus, dass Breite oder Höhe nicht angegeben wurden.
Was jetzt aber noch nicht funktioniert, ist die Einbindung in den bestehenden HTML-Code mittels $Ausgabe .= '<img src="Verkleinern.php?Bild=' . $Bild . '&Hoehe=95">';
Das ist so ärgerlich, so kurz vor einer weiteren Ziellinie wieder zu stolpern :-|
Die zu verkleinernden Grafiken sollten in obiger Grafik zwischen der Artikelbezeichnung und dem Preis stehen.
An der Variablen $Ausgabe kann es aber nicht liegen, denn wenn ich Grafiken hart einbinde, dann werden diese angezeigt.
Liegt es daran, dass ich keine Größenangaben hinterlegt habe?
Wieso klappt die direkte Eingabe im Browser, nicht aber die Ausgabe innerhalb des HTML-Codes?
Gruß,
Enrico
Tach!
if (isset ($_GET['Bild']) && $_GET['Bild'] !== "")
{
Du hast mich nicht richtig verstanden. Diese beiden Abfragen lassen sich mit empty() zusammenfassen. (Zudem wäre der typsichere Vergleich bei $_GET/$_POST nicht sinnvoll, weil sowieso nur Strings dort drinstehen.) Das empty() hatte ich an der Stelle eigentlich nur zur zusätzlichen Information aufgeführt. Mein Vorschlag hier war jedoch, (nur) das isset() zu lassen und dazu den korrigierten RegExp als eine Art Dateinamensprüfung. Diese sollte zumindest verhindern, dass anderswohin als ins vorgesehene Verzeichnis gegriffen werden kann. Das Ausschließen von . ist da schon ein Anfang.
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
if (file_exists ($Bild))
Ohne den RegExp prüfst du jetzt nur, ob es eine Datei ist. Die kann sich aber aufgrund von ../-Teilen im Parameter irgendwo befinden. Damit kann man zumindest unberechtigt Grafikdateien zur Ausgabe bringen.
Die Prüfung sollte also sicherstellen, dass $_GET['Bild'] vorhanden ist, mit dem RegExp, dass es nicht leer und nur Buchstaben/Zahlen enthalten sind, und dass das Ergebnis auf eine Datei zeigt.
if (isset ($_GET['Breite']) && $_GET['Breite'] !== "")
{
if (is_numeric ($_GET['Breite']))
Hier und bei der Höhe kannst du zu if (!empty(...) and is_numeric(...)) zusammenfassen. Bei Höhe jedoch ifelse und das else danach bringt die Fehlermeldung. Allerdings ist die Fehlermeldung nur zum Debugging sinnvoll, denn normalerweise wird das Script ja von <img> aufgerufen, und dann sind keine Textausgaben zu sehen.
$Bild = $Thumbnail;
imagepng ($Bild, "", 9);
Das Umkopieren ist überflüssig. Lass das weg und übergib dem imagepng() gleich $Thumbnail.
Ist das mit dem Erhalt der vormaligen Transparenz kompliziert?
Kann ich dir nicht beantworten.
Nebenbei: wenn ich, so wie Chris es vorgeschlagen hatte, das "&" escape und statt dessen "&" schreibe, dann läuft mir das Skript bei der Abfrage nach Breite und Höhe in den finalen else-Zweig und spuckt mir meine Fehlermeldung aus, dass Breite oder Höhe nicht angegeben wurden.
Das & darf nur im HTML-Kontext angewendet werden. Die Eingabezeile des Browsers ist kein HTML, also wäre das dort fehl am Platz.
Was jetzt aber noch nicht funktioniert, ist die Einbindung in den bestehenden HTML-Code mittels $Ausgabe .= '<img src="Verkleinern.php?Bild=' . $Bild . '&Hoehe=95">';
Liegt es daran, dass ich keine Größenangaben hinterlegt habe?
Wieso klappt die direkte Eingabe im Browser, nicht aber die Ausgabe innerhalb des HTML-Codes?
Das vermag ich jetzt nicht zu erkennen. Ersetz doch mal alle echo durch file_put_contents('error.log', 'hierdiemeldung', FILE_APPEND); Das error.log soll in ein Verzeichnis zeigen, in das der Webprozess schreiben darf. Am besten wäre außerhalb des DocumentRoot. Jedenfalls solltest du nun nachträglich sehen, was dein Script gemacht hat, wenn es eingebunden ist. Zusätzliche Kontrollausgaben dorthin wären im weiteren Verlauf des Debuggings sinnvoll.
dedlfix.
Hey Enrico,
Was jetzt aber noch nicht funktioniert, ist die Einbindung in den bestehenden HTML-Code mittels $Ausgabe .= '<img src="Verkleinern.php?Bild=' . $Bild . '&Hoehe=95">';
prüfe mal an der Stelle, an der Du die Ausgabe erzeugst, mit var_dump($Bild) oder Ähnlichem, von welchem Typ die Variable $Bild ist. Ich hab mir Deinen Code nicht komplett angesehen, könnte mir aber vorstellen, dass durch das wilde rumkopieren $Bild eine Bildressouce und kein String ist.
Gruß, Dennis
Ps: War lang nicht mehr hier im Forum, nachdem es lange nicht funktioniert hatte. Ist schick geworden.
Om nah hoo pez nyeetz, Der-Dennis!
Ps: War lang nicht mehr hier im Forum, nachdem es lange nicht funktioniert hatte. Ist schick geworden.
Danke.
Matthias
Hallo Dennis,
hallo dedlfix,
gettype ($Bild) liefert mir "string"
var_dump ($Bild) liefert mir "GewandungMuetzen1"
Dies würde bedeuten, dass die Variable $Bild, trotz der Änderungen, trotz der Funktionen wieder/immer noch die ursprüngliche Belegung enthält?
Ich setz jetzt mal die Anregungen von dedlfix um und schau mal, ob sich etwas ändert ^^
Gruß,
Enrico
Nochmals Hallo,
so, hier der verbesserte Code:
<?php
ParameterHolen ();
function ParameterHolen ()
{
if (isset ($_GET['Bild']) && preg_match ("/^[a-z]+[0-9]+$/i", $_GET['Bild']))
{
$Bild = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
if (file_exists ($Bild))
{
if (isset ($_GET['Breite']) && is_numeric ($_GET['Breite']))
GroesseBerechnen ($Bild, $_GET['Breite'], "");
elseif (isset ($_GET['Hoehe']) && is_numeric ($_GET['Hoehe']))
GroesseBerechnen ($Bild, "", $_GET['Hoehe']);
else
echo 'Variable "Breite" oder "Hoehe" fehlt oder ungültig';
}
else
echo 'Datei "' . $Bild . '" nicht gefunden';
}
else
echo 'Variable "Bild" fehlt oder ungpltig';
}
function GroesseBerechnen ($Bild, $xNeu, $yNeu)
{
if ($Groesse = getimagesize ($Bild))
{
$x = $Groesse[0];
$y = $Groesse[1];
if ($xNeu != "")
{
$yNeu = round ($y / ($x / $xNeu));
$xNeu = round ($x / ($y / $yNeu));
BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu);
}
else
if ($yNeu != "")
{
$xNeu = round ($x / ($y / $yNeu));
$yNeu = round ($y / ($x / $xNeu));
BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu);
}
else
echo 'Funktion "GroesseBerechnen": Breiten- oder Höhenangabe fehlt';
}
else
echo 'Funktion "GroesseBerechnen": "getimagesize" ist fehlgeschlagen';
}
function BildErzeugen ($Bild, $x, $y, $xNeu, $yNeu)
{
$Bild = imagecreatefrompng ($Bild);
if (! $Thumbnail = imagecreatetruecolor ($xNeu, $yNeu))
$Thumbnail = ImageCreate($xNeu,$yNeu);
if (! imagecopyresampled ($Thumbnail, $Bild, 0, 0, 0, 0, $xNeu, $yNeu, $x, $y))
imagecopyresized ($Thumbnail, $Bild, 0, 0, 0, 0, $xNeu, $yNeu, $x, $y);
header("Content-type:image/png");
imagepng ($Thumbnail, "", 9);
}
?>
Nach wie vor das gleiche Resultat, dass es bei direkter Eingabe klappt:
Bei Einbindung in den HTML-Code hingegen nicht:
Wie bereits geschrieben liefert mir gettype ($Bild) "string" und var_dump ($Bild) "GewandungMuetzen1".
Alle echo-Befehle durch file_put_contents('error.log', 'hierdiemeldung', FILE_APPEND); zu ersetzen erfordert ein komplettes Umschreiben des Codes, da ich die Ausgaben zusammensetze:
$Ausgabe .= '<div class="Artikel">';
$Ausgabe .= '<div class="Bezeichnung">' . $Link . '</div>';
$Ausgabe .= '<img src="Verkleinern.php?Bild=' . $Bild . '&Hoehe=95">';
$Ausgabe .= '<div class="Rabatt"></div>';
$Ausgabe .= '<div class="Preis">' . $Preis . '</div>';
$Ausgabe .= "</div>";
Es ist deshalb notwendig, die eigentliche Ausgabe so zusammenzusetzen, da vorher verschiedene Abfragen erfolgen und das Zusammensetzen der Variable $Ausgabe von diesen Abfragen an mehreren Stellen abhängt.
Ich versteh nicht, warum es nicht funktioniert.
Gruß,
Enrico
Tach!
Alle echo-Befehle durch file_put_contents('error.log', 'hierdiemeldung', FILE_APPEND); zu ersetzen erfordert ein komplettes Umschreiben des Codes, da ich die Ausgaben zusammensetze:
$Ausgabe .= '<div class="Artikel">';
$Ausgabe .= '<div class="Bezeichnung">' . $Link . '</div>';
Ein Script, das eine Grafik ausgeben soll, hat nur diese Grafik als Ausgabe. Der Content-Type ist image/png und nicht image/png+text/html oder image/png+text/plain. Solche Mischformate gibt es nicht. Eine Ressource = eine Content-Type = eine Inhaltsform. In einem Grafik-Script haben andere Texte (inklusive HTML-Code) nichts zu suchen, es sei denn, diese landen während der Bearbeitung in der Grafik. Selbst Fehlermeldungstexte sind für den normalen Betrieb fehl am Platz. Deswegen muss es problemlos möglich sein, diese Fehlermeldungstexte in eine Datei auszugeben.
Ich versteh nicht, warum es nicht funktioniert.
Im Moment ist das Verstehen zweitrangig, weil die Ursache noch unbekannt ist. Dieser gilt es zunächst sich mit passendem Debugging anzunähern. Erst wenn du weißt, was genau passiert, kommt das Verständnis vielleicht von selbst, oder man kann dafür eine Erklärung suchen.
dedlfix.
Hallo dedlfix,
ich verstehe jetzt gar nichts mehr...
Die Datei "Verkleinern.php" besteht nur aus dem initialen Funktionsaufruf "ParameterHolen ()", der gleichnamigen, eigentlichen Funktion "ParameterHolen ()" und den weiteren Funktionen "GroesseBerechnen" sowie "BildErzeugen ()", aber keinem weiteren Code.
In der Datei "Sortiment.php" wird die Grafik an die Datei "Verkleinern.php" im img-Tag als Parameter mit Breiten- oder Höhenangabe für die Bearbeitung übergeben, die Ausgabe zusammengesetzt und der eigentliche Quelltext ausgegeben.
Das Skript funktioniert, das Einbinden nicht.
...
Gruß,
Enrico
Tach!
Die Datei "Verkleinern.php" besteht nur aus dem initialen Funktionsaufruf "ParameterHolen ()", der gleichnamigen, eigentlichen Funktion "ParameterHolen ()" und den weiteren Funktionen "GroesseBerechnen" sowie "BildErzeugen ()", aber keinem weiteren Code.
Ok, aber in ihr sind auch Textausgaben enthalten, nämlich die in den else-Zweigen. Die sollst du umschreiben als Dateiausgabe. Du kannst auch noch eine Funktion namens logtext($msg) anlegen (log allein geht nicht, ist schon verwendet), und darin den file_put_contents()-Aufruf notieren. Das ist dann am Ende nur noch eine Zeile, die du bei Bedarf einfach gegen echo oder was anderes austauschen kannst.
In der Datei "Sortiment.php" wird die Grafik an die Datei "Verkleinern.php" im img-Tag als Parameter mit Breiten- oder Höhenangabe für die Bearbeitung übergeben, die Ausgabe zusammengesetzt und der eigentliche Quelltext ausgegeben.
Dessen Ausgabe kannst du so lassen wie sie ist. In einem Script wie diesem, das Text (oder HTML-Code) als Ausgabe erzeugt, könntest du einfach Debug-Ausgaben einfügen. Aber in dem Grafik-Script geht das nicht, weswegen du dort auf Dateiausgabe umsteigen sollst. Das Grafik-Script verkleinern.php wird ja indirekt aufgerufen und dessen Debugausgaben sind im Moment interessant, damit du sehen kannst, was es während dieses indirekten Aufruf wird.
dedlfix.
Hello Enrico,
<?php
function ParameterHolen ($_GET)
{
$_ret ['error'] = 999; ## schreiben wir mal prophilaktisch rein
if (isset ($_GET['Bild']) && preg_match ("/[1]+[0-9]+$/i", $_GET['Bild']))
{
$_ret ['bildname'] = "../GRAFIKEN/SORTIMENT/" . $_GET['Bild'] . ".png";
if (file_exists ($_ret ['bildname']))
{
if (isset ($_GET['Breite']) && is_numeric ($_GET['Breite']))
GroesseBerechnen ($Bild, $_GET['Breite'], "");
elseif (isset ($_GET['Hoehe']) && is_numeric ($_GET['Hoehe']))
GroesseBerechnen ($Bild, "", $_GET['Hoehe']);
else
## echo 'Variable "Breite" oder "Hoehe" fehlt oder ungültig';
$_ret ['errtxt'] = 'Parameter "Breite" oder "Hoehe" fehlen oder sind ungültig';
return $_ret;
}
else
## echo 'Datei "' . $Bild . '" nicht gefunden';
$_ret ['error'] = 998; ## Parameterfehler, Nummer ist frei erfunden
## mach Dir eine Liste
$_ret ['errtxt'] = 'Datei "' . $Bild . '" nicht gefunden';
return $_ret;
}
else
echo 'Variable "Bild" fehlt oder ungpltig';
$_ret ['error'] = 0; ## kein Fehler aufgetreten
$_ret ['errtxt'] = false; ## Kein Fehler, kein Fehlertext
return $_ret;
}
?>
Bitte beschäftige Dich nochmal mit Funktionen.
PHP ermöglicht es den Funktionen, ein Array zurückzugeben.
Dieses könnte so ausehen:
$\_ret = array();
$\_ret['error'] = 0; (kein Fehler aufgetreten)
$\_ret['errtxt'] = verbale Fehlerbeschreibung, wenn ein Fehler aufgetreten ist
$\_ret['breite'] = ... (Wert eintragen)
$\_ret['hoehe'] = ... (wert eintragen)
Du rufst die Funktion dann z.B. so auf:
$\_params = ParameterHolen ($\_GET);
und fragst anschließend, ob $\_params === 0 ist. Dann hat die Funktion ordentlich gearbeitet und Du kannst mit dem nächsten Arbeitsschritt weiterarbeiten. In denübrigen Elementen des Rückgabearrays sollten dann die passenden Werte drinstehen.
Dafür musst Du natürlich in der Funktion sorgen.
Das Schöne an dieser Vorgenensweise ist, dass man Funktionen auch später noch immer erweitern kann, es kommen eben nur einfach weitere Rückgabeparemeter hinzu. Ältere Applikationen können aber trotzdem die neue Funktionsbibliothek benutzen, solange sie "ihre" Paramteter noch in den Rückgabearrays finden können.
Probier es mal zuerst mit der ersten Funktion, bei der ich das schon angedeutet habe, wie es gehen könnte.
Und weil es so schön schmutzig ist, also nicht sauber prozedural nach Nassi Shniderman, kann man die geschachtelten Ifs auch meistens durch gestaffelte ifs austauschen, wenn man nach Auftreten eines Fehlers einfach den Fehlerwert ins Ergebnisarray einträgt und dieses dann mittles "return $\_ret" zurückgibt.
Die Funktion wird dann ja beendet und die übrigen Aktionen finden nicht mehr statt.
Das widerspricht zwar - wie schon geschrieben - den Vorgaben für saubere strukturierte Programmierung, macht die Funktionen aber viel leichter lesbar und vermeidet viel Schreibarbeit und Klammernkontrolle.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
☻\_
/▌
/ \ Nur selber lernen macht schlau
<http://restaurant-zur-kleinen-kapelle.de>
a-z ↩︎
Hello,
PHP ermöglicht es den Funktionen, ein Array zurückzugeben.
Dieses könnte so ausehen:$_ret = array();
$_ret['error'] = 0; (kein Fehler aufgetreten)
$_ret['errtxt'] = verbale Fehlerbeschreibung, wenn ein Fehler aufgetreten ist
$_ret['breite'] = ... (Wert eintragen)
$_ret['hoehe'] = ... (wert eintragen)Du rufst die Funktion dann z.B. so auf:
$_params = ParameterHolen ($_GET);
und fragst anschließend, ob $_params ['error'] === 0 ist.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
$_ret = array();
$_ret['error'] = 0; (kein Fehler aufgetreten)
$_ret['errtxt'] = verbale Fehlerbeschreibung, wenn ein Fehler aufgetreten ist
$_ret['breite'] = ... (Wert eintragen)
$_ret['hoehe'] = ... (wert eintragen)Du rufst die Funktion dann z.B. so auf:
$_params = ParameterHolen ($_GET);
und fragst anschließend, ob $_params ['error'] === 0 ist.
Warum typsicher? Es ist doch nur ein ja/nein-Wert, also kann und sollte man den auch boolesch abfragen und setzen. Allerdings ist er überflüssig, denn die Information ob Fehler aufgetreten sind oder nicht, kann man dem gefüllten oder leeren Fehlermeldungstext-Array (oder auch einfachem String) entnehmen. if ($_ret['errtxt']) { fehler ... } else { bestens ... }
dedlfix.
Hello,
Warum typsicher?
jetzt ist meine Antwort schon wieder verschwunden. Irgendwas stimmt hier nicht.
Ich hatte extra darauf geachtet, dass ich _erst_ Voschau und dann noch _Beitrag__absenden_ gedrückt habe. Wo bleibt das Zeug?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
jetzt ist meine Antwort schon wieder verschwunden. Irgendwas stimmt hier nicht.
Ich hatte extra darauf geachtet, dass ich _erst_ Voschau und dann noch _Beitrag__absenden_ gedrückt habe. Wo bleibt das Zeug?
Im Logfile stehen nur GET-Requests. Erst 11:27:33 kommt ein anonymer POST, der mit 401 beantwortet wurde, gefolgt von einem namentlichen zur selben Zeit, der ein 200 bekommt. 11:27:59 kommt noch ein POST mit 302 als Antwort. Dazwischen stehen keine GETs. Also schlussfolgere ich, dass nur die POSTs vom Beschwerdeposting hier angekommen sind.
dedlfix.
Hello,
jetzt ist meine Antwort schon wieder verschwunden. Irgendwas stimmt hier nicht.
Ich hatte extra darauf geachtet, dass ich _erst_ Voschau und dann noch _Beitrag__absenden_ gedrückt habe. Wo bleibt das Zeug?Im Logfile stehen nur GET-Requests. Erst 11:27:33 kommt ein anonymer POST, der mit 401 beantwortet wurde, gefolgt von einem namentlichen zur selben Zeit, der ein 200 bekommt. 11:27:59 kommt noch ein POST mit 302 als Antwort. Dazwischen stehen keine GETs. Also schlussfolgere ich, dass nur die POSTs vom Beschwerdeposting hier angekommen sind.
Tja, dann muss ich mir wohl doch mal über "man in the middle" Gedanken machen.
Jetzt, wo ich wonaders sitze, scheint es ja wieder einwandfrei zu funktionieren!
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo Tom,
für mich spielt der Programmierstil erst mal eine untergeordnete Rolle, da das Endergebnis für mich zählt.
Wenn ich Dir aber auch recht geben muss, dass eine saubere(re) Programmierung es einem erleichtert, Fehler zu suchen und zu beseitigen.
Das Skript funktioniert ja, das sehe ich an der direkten Eingabe im Browser.
Ich hänge jetzt "nur" noch daran, dass es in HTML nicht korrekt eingebunden wird.
Gruß,
Enrico
Hey Enrico,
Bei Einbindung in den HTML-Code hingegen nicht:
ich hab das Script aus Deinem Post gerade mal bei mir ausprobiert und dazu einfach eine HTML-Datei mit dem Inhalt
<html>
<head>
<title>Thumnail-Test-Seite</title>
</head>
<body>
<h1>Thumbnail-Test-Seite</h1>
<img src="test.php?Bild=test&Breite=90" />
</body>
</html>
verwendet, wobei die test.php 1:1 Deiner geposteten Lösung entspricht. Zum Testen habe ich ein Bild namens test.png verwendet. Und das funktioniert ohne Probleme, das Bild wird als Thumbnail angezeigt.
Ich vermute also, der Hund liegt woanders begraben. Bist Du mit dedlfix Vorschlag vorangekommen?
Gruß, Dennis
Hallo,
Asche über mein Haupt, es funktioniert :-)
Ich trau es mich fast nicht zuzugeben, dass es "nur" daran lag, dass der Pfad zur Datei "Verkleinern.php" unvollständig war.
Vielen, vielen, vielen Dank an euch, dazu gelernt habe ich auf jeden Fall, und bitte nichts für ungut!
Gruß,
Enrico
Jetzt muss ich es nur noch hinbekommen, dass meine transparenten Bilder auch transparent bleiben und keinen schwarzen Hintergrund haben.
Gruß,
Enrico
Mittels imagecolortransparent ($Thumbnail, imagecolorallocate($Thumbnail, 0, 0, 0)); hat es geklappt, wenn ich jetzt auch leider einen unschönen Treppeneffekt bei Rundungen habe, das kann aber auch mit der Verkleinerung zusammenhängen (PHP ist halt nicht Photoshop).
Mit imagealphablending($Thumbnail, false); und imagesavealpha($Thumbnail, true); geht es, zumindest in meinem Fall, warum auch immer, nicht.
Gruß,
Enrico
Tach!
Ich trau es mich fast nicht zuzugeben, dass es "nur" daran lag, dass der Pfad zur Datei "Verkleinern.php" unvollständig war.
Firebug zum Beispiel hat einen Reiter "Netzwerk". Damit siehst du alles was angefordert und den Statuscode dazu sehr übersichtlich. Damit hätte dir der 404er auffallen können.
Vielen, vielen, vielen Dank an euch, dazu gelernt habe ich auf jeden Fall, und bitte nichts für ungut!
Ansonsten, die Sache mit dem Umschreiben der echo-$fehlermeldung;-Zeilen solltest du dir trotzdem noch vornehmen.
dedlfix.