• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Bild ohne Zwischenspeichern skalieren

J

j-l-n

Guest
Ich erzeuge ein Bild mit PHP. Auf dieses wird z.B. mittels
PHP:
imagettftext($background, $size, $angle_3, $x_align_3, $y_align, $color3, $fonts[2], $string3);
geschrieben.

Ausgegeben wird das Ganze zum Schluss via
PHP:
imagejpeg($background);
direkt im Browser.


Nun möchte ich das fertige Bild allerdings noch verkleinern. Dafür benutze ich folgende Funktion:

PHP:
$filename = 'temp_bild.jpg';

// Set a maximum height and width
$width = 200;
$height = 200;

// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);

$ratio_orig = $width_orig/$height_orig;

if ($width/$height > $ratio_orig) {
   $width = $height*$ratio_orig;
} else {
   $height = $width/$ratio_orig;
}

// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

// Output
imagejpeg($image_p, null, 100);

Will ich aber diese Funktion nutzen, muss ich das oben erzeugte Bild immer erst mittels
PHP:
imagejpeg($background, "temp_bild.jpg", 90);
auf dem Server speichern.

Gibt es einen Weg, direkt aus dem oben erzeugten Bild ohne Zwischenspeichern die kleinere Version zu erzeugen? Denn wenn ich es in der Art
PHP:
$filename = imagejpeg($background);
übergebe, klappt es nicht...
 
Schau mal in der Doku:
filename

Der Pfad unter dem das Bild gespeichert werden soll. Ist dies nicht gesetzt oder NULL wird der rohe Bilddatenstrom direkt ausgegeben.
Das heißt, imagejpeg($image_p, NULL, 100); sollte das Bild schon direkt zum Browser auf STDOUT senden. Verstehe das Problem nicht ganz.
Vielleicht muss das NULL wirklich groß geschrieben werden?
 
Zuletzt bearbeitet:
Das Bild, das skaliert werden soll, ist ja keine lokale Bilddatei, sondern ebenfalls ein durch PHP erzeugtes Bild. Und dieses dynamisch erzeugte Bild möchte ich vor dem Skalieren nicht speichern müssen, um es skalieren zu können.
 
Ja, und laut Doku soll das möglich sein, indem man den Dateinamen im Aufruf auf NULL setzt. Tut denn dieser Befehl imagejpeg($image_p, null, 100); nicht was er soll?
 
Ich glaub, wir missverstehen uns hier. Deswegen mal das ganze Skript:

PHP:
//Bilddatei erzeugen
$background = imagecreatefrompng("background.png");

$size = 200;
$y_align = 250;
$angle = 5;

$x_align = 50;
$x_align_2 = $x_align + 200;

$color = imagecolorallocate($background, 200, 50, 150);

 
//Bild zusammenbauen
imagettftext($background, $size, $angle_1, $x_align, $y_align, $color, $fonts[0], $string1 );
imagettftext($background, $size, $angle_2, $x_align_2, $y_align, $color, $font, $string2 );



/*
So, bis hierhin habe ich jetzt also das Bild bearbeitet und Text darauf geschrieben.
Nun würde ich es mit
imagejpeg($background);
direkt ausgeben.
Allerdings möchte ich es davor noch skalieren. Und wie mache ich das jetzt, d.h., was muss ich für $filename einsetzen?
*/

$filename = ?????

// Set a maximum height and width
$width = 200;
$height = 200;

// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);

$ratio_orig = $width_orig/$height_orig;

if ($width/$height > $ratio_orig) {
   $width = $height*$ratio_orig;
} else {
   $height = $width/$ratio_orig;
}

// Resample
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($background, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

// Output
imagejpeg($image_p, null, 100);
 
Achso!! OK, dann würde ich einfach STDOUT in eine Variable umleiten und nach dem Kommando wieder zurück. Ich weiß nur leider nicht, wie das in PHP geht. Aber das sollte Google wissen.
 
So funktioniert es leider nicht:

PHP:
ob_start();
imagepng($background);
$image_data = ob_get_contents();
ob_end_clean();

// The file
$filename = "background.png";

// Set a maximum height and width
$width = 200;
$height = 200;

// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);

$ratio_orig = $width_orig/$height_orig;

if ($width/$height > $ratio_orig) {
   $width = $height*$ratio_orig;
} else {
   $height = $width/$ratio_orig;
}

// Resample
$image_p = imagecreatetruecolor($width, $height);
imagecopyresampled($image_p, $image_data, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);

// Output
imagejpeg($image_p, null, 90);
 
Äh... du hast da doch schon imagecopyresampled im Code drin... da kopierst du von einer Bildressource zur anderen - und zwar skalierend ($width vs. $width_orig und $height vs. $height_orig).
Das kannst du doch einfach mit deinem $background und einer neuen Bildressource, die die richtige Größe hat, machen.

PS: wenn du das Bild komplett mit PHP erzeugst, warum erzeugst du es dann nicht gleich kleiner?
 
Das kannst du doch einfach mit deinem $background und einer neuen Bildressource, die die richtige Größe hat, machen.

Also dann so?
PHP:
imagecopyresampled($image_p, $background, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
Oder anders?


PS: das Bild wird nicht komplett von PHP erzeugt. Der Hintergrund ist nämlich eine normale PNG-Datei.
 
Schau dir mal das Stack an bitte: png - Cropping an image in PHP - Stack Overflow
Da wird der Inhalt der Variable für den zweiten Parameter für imagecopyresampled() nicht mit imagepng() sondern mit imagecreatefrompng() erzeugt. Könnte es daran liegen? Hast du mal kontrolliert, was in $image_data drin steht, nachdem du das aus dem STDOUT Puffer gelesen hast? Wäre das überhaupt ein gültiger binärer Datenstrom für ein Image, wenn man es wiederum testweise mit echo an den Browser schicken würde? Gibt es einen Unterschied zu dem, was imagecreatefrompng() liefert? Was genau geht mit dem Code aus #8 nicht?
 
Hast du mal kontrolliert, was in $image_data drin steht, nachdem du das aus dem STDOUT Puffer gelesen hast? Wäre das überhaupt ein gültiger binärer Datenstrom für ein Image, wenn man es wiederum testweise mit echo an den Browser schicken würde?

Ja, ist es. Wenn ich
PHP:
echo $image_data;
ausgeben lasse, wird das Bild korrekt angezeigt.
 
Jo, dann liegt der Fehler aber an einer anderen Stelle und dürfte nichts mit dem Abgreifen von STDOUT zu tun haben. Musst du mal Zeile für Zeile mit echo Ausgaben debuggen, was da genau passiert.
 
sieht gut aus... funktioniert es denn?

Mittlerweile, nachdem ich einen Fehler noch ausgebügelt habe, funktioniert es tatsächlich.
Anscheinend kann man mit imagecopyresampled() jedoch wirklich nur "richtige" Bilddateien kopieren, denn
PHP:
ob_start();
imagepng($background);
$image_data = ob_get_contents();
ob_end_clean();
//...
imagecopyresampled($image_p, $image_data, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
klappt nicht. Per
PHP:
echo $image_data;
wird das Bild aber korrekt ausgegeben, von daher müsste der zweite Parameter doch korrekt sein!?


Naja, auf jeden Fall ist das Problem damit gelöst!
 
wird das Bild aber korrekt ausgegeben, von daher müsste der zweite Parameter doch korrekt sein!?
Ein Reihe von Bytes, die der Browser als Bilddatei erkennt und dann richtig darstellt ist was ganz anderes als eine Ressource, die ein Bild im Arbeitsspeicher hält und noch Funktionalität dazu bereithält.

Als JS-Beispiel fällt mir jetzt nur:
Code:
var str = '{"test":1}';
// vs
var obj = {"test": 1};
ein.
 
Zurück
Oben