class.Images.php
Last changes on this page: July 19, 2010
A PHP class to rotate, crop and resize images. Can be used to create thumbnails etc.
Eine PHP-Klasse zum Rotieren, Beschneiden und Verändern der Grösse von Bildern.
Yes, I know. It is yet another image manipulation class for PHP. But so far I haven’t found the one that really matches my needs. Either they are too complicated or bound to another system. So I simply created my own class with just the functions I need. So it’s the perfect class for me. If you like it, too – even better! To illustrate what the class can do I’ll use this photo of a hot dog. Hope you’re not hungry!
You’re welcome!
Do you like this class? You’re invited to donate a few bucks.
You know, Thank You Economy and all that stuff…
I promise I won’t get high on it.
Installation
- Download source code right here, right now!
- That’s it. Get going!
Example
Here’s a basic example of what you can do and this is what you’ll get with it.
//Create a new object, send relative or absolut path to your image
$image = new Image("/path/to/hotdog.jpg");
//Optionally you can set a path to where temporary files shall be saved. If you don't set this path, the class will try to save the temp files in the working directory.
$image->setPathToTempFiles("/path/to/tempfolder");
//We can rotate the image
$image->rotate(90);
//and we can resize and crop it to have a nice thumbnail
$image->resize(150,150,"crop");
//lets see what we have!
$image->display();
Save files
Of course you want to save the new files. Of course you can.
require_once("class.Images.php");
$image = new Image("hotdog.jpg");
$image->setPathToTempFiles("/path/to/tempfolder");
$image->rotate(90);
//Now save the file. First give a filename (without file extension, the class will figure it out!)
//Then, optionally, give path to the folder where you want the image to be saved.
$image->save("newFilename", "../directory/of/save");
//and... oh pretty wow! If the path of the image is accessible to the browser
//you can now even display the whole HTML code of the <img alt="" />-Tag
$image->displayHTML();
Fit, fill or crop
The beauty of the class lies within the resize method. Check this out.
//If you resize an image, the standard value is "fit". This means, your image
//will be resized so it fits within the provided width and height without
//losing its aspect ratio. So what you deliver is basically the maximum
//width and height of the new image, but very likely one side of the
//image will turn out smaller.
$image = new Image("hotdog.jpg");
$image->setPathToTempFiles("/path/to/tempfolder");
$image->resize(300,100);
$image->save("file1");
$image->displayHTML();
//If you set the option "fill" the image will fill the whole width and
//height you provided. But it will loose it aspect ratio. So be ready
//to see your image deformed.
$image = new Image("hotdog.jpg");
$image->setPathToTempFiles("/path/to/tempfolder");
$image->resize(300,100, "fill");
$image->save("file2");
$image->displayHTML();
//If you choose to "crop" the image, it won't lose its aspect ratio but
//parts of the image will be cut off.
$image = new Image("hotdog.jpg");
$image->setPathToTempFiles("/path/to/tempfolder");
$image->resize(300, 100, "crop");
$image->save("file3");
$image->displayHTML();
Crop it like it’s hot
Now, there’s more to cropping! You can choose which part of the original image you want to see on the cropped image. Simply set l, r, or c for left, right or center and b, t or c for bottom, top or center. Go play around, not all combinations make sense for every image. It depends whether the image’s format is landscape or portrait. Here are some examples of our hotdog (by the way, still not hungry?).
$image->resize(300, 100, "crop", "l", "b");
//Start at left top corner
$image->resize(300, 100, "crop", "l", "t");
//Start at left side of image, center of height
$image->resize(300, 100, "crop", "l", "c");
Do you two match together?
Let’s say you want your user to upload an image which has an exact aspect ratio of 1:2. How do you check that? Nothing easier than that!
if($image->checkRatio(1,2)){
print "Yes, you made it!";
}else{
print "Sorry dude, try again.";
}
All you your knowledge are belong to us
There’s so much to know about an image. Go get some information!
print "Width: ".$image->getWidth()."
";
print "Height: ".$image->getHeight()."
";
print "Extension: ".$image->getExtension()."
";
print "Mime: ".$image->getMimeType()."
";
print "Type: ".$image->getType()."
";
print "Filesize in Bytes: ".$image->getFileSizeInBytes()."
";
print "Filesize in kBytes: ".$image->getFileSizeInKiloBytes()."
";
print "Filesize readable: ".$image->getFileSize()."
";
print "Ratio Width:Height: ".$image->getRatioWidthToHeight()."
";
print "Ratio Height:Width: ".$image->getRatioHeightToWidth()."
";
print "Is it RGB?: ".$image->isRGB();
//The output:
# Width: 500
# Height: 298
# Extension: jpg
# Mime: image/jpeg
# Type: jpeg
# Filesize in Bytes: 89166
# Filesize in kBytes: 87.076171875
# Filesize readable: 87 KB
# Ratio Width:Height: 1.67785234899
# Ratio Height:Width: 0.596
# Is it RGB?: true
Add watermarks
Added July 19, 2010
Want to protect your image from greedy thieves? Add a watermark to it!
$Watermark = $image->addWatermark("anotherImage.png");
//do crazy stuff with it!
//Beware: This may turn out buggy with images with transparency
$Watermark->rotate(45);
$Watermark->resize(50,50,"crop");
//write it in the main image
$image->writeWatermark();
There are several options you can set when writing the watermark, like opacity and position. Have a look at the source code of the class to find out what you can do as I’m being lazy right now :)
Feedback?
That’s it. With this class you can propably cover most of the things you need to do with images. Of course there is much more possible. Go ahead and extend the class. I’ll be more than happy to implement it into the downloads here.
Get in touch: @sprain on Twitter or email me.
Kommentare
Kommentar abgeben
Trackbacks
-
05. Mai 2010 um 14:16 Uhr
class.Images.php – eine PHP-Klasse zur Bildmanipulation | sprain's

Uh, fremder Code zum Kritisieren. Was gibt’s schöneres?
Zeile 44: Kennst du tempnam()? :-)
Zeile 74: Die Funktion könnte doch auch gleich den Array $this->imageInfo zurückgeben.
Zeile 103: Mit realpath() könntest du auch noch gleich die Existenz des temporären Verzeichnisses testen und den Pfad säubern. Plus dann weisst du, dass das Trailing Slash sicher fehlt, welches du dann mit DIRECTORY_SEPARATOR einfach anhängen kannst.
Zeile 337: Funktioniert nicht, wenn ein Windows-Pfad mit \ ankommt. Darum eben lieber realpath() benutzen und die Konstante DIRECTORY_SEPARATOR.
Ab Zeile 281: functions haben keinen private/public-Modifikator mehr.
Zeile 593: Das ?> schreibt man am Schluss nicht mehr.
Das Dauerproblem mit den blöden Image-Funktionen (imageCreateFroJPEG()…) hast du elegant gelöst. :-)
Was für ein Editor macht dir dir ganzen //if und so?
@Christian
Oh cool, danke! Habs gleich angepasst.
Zeile 44:
tempnam() kannte ich echt nicht. Ist jetzt eingebaut.
Zeile 74:
Dafür nimmst du getImageInfo()
Zeile 103/337:
realpath und DIRECTORY_SEPARATOR eingebaut. Du siehst, im Filesystem codiere ich selten :)
Ab Zeile 281:
Gingen vergessen, jetzt ergänzt. Danke
Zeile 593:
Aber mir gefällt das ?>. Ist für mich auch ein EOF-Zeichen, das File ist komplett, ich hab nix aus Versehen abgeschnitten.
@Christan
Ach ja, der Editor der die //function hinten an die geschweiften Klammern macht heisst sprain :) Hab ich mir einfach angewöhnt.
Bitte…
Das mit dem ?> kann dir einfach hässliche Fehler generieren, wenn du hinten noch ein Leerzeichen hast.
Fürs Ende hättest du ja dein }//class. :-)
Mal sehen, vielleicht kann ich deine Klass demnächst gut gebrauchen und werde Änderungen zurückmelden.
cool, gut zu wissen, dass es hier ne anständige Bilddingsbums-Klasse gibt. Danke fürs sharen. Und hopp auf Delicious damit… :)
Seh ich das richtig, oder lädt displayHTML die Bilder vom absouluten Pfad des Servers ‘/var/htdocs/……/fotos/bild.jpg’?
@nik
Eigentlich nicht, aber ich schliesse nicht aus, dass da irgend ein Bug besteht. Hast du ein Codebeispiel, wie dies bei dir geschieht?
Heute mit Update! Unter anderem ist das Problem von @nik in vielen Fällen behoben.
Hallo sprain,
leider hatte ich die url verloren und auch deine Klasse hab ich nicht mehr gefunden, weil ich in vielen Projekten unterschiedlichste eingesetzt hatte.
Aber -das ist jetzt keine übertriebene Lobhuddelei- deine Klasse gefällt mir 100mal besser als alles was da draußen so rumläuft und so hab ich meine ganze Festplatte und mehrere files durchsucht, um sie endlich wiederzufinden!
Umso peinlicher ist es mir, dass ich meinen Kommentar nicht weiterverfolgt habe und dir kein Beispiel geliefert hatte :-( Schande…
Werd mir gleich mal die aktuelle Version ziehen.
Liebe Grüße und vielen Dank für deine Mühe!
@nik
Na, dann vielen Dank und willkommen zurück! Ich hoffe, dass es jetzt klappen wird bei dir.
Hat schon davor geklappt, hatte ein bisschen drin rumgepfuscht…
Werds mal bei Gelegenheit testen, dann gibts Feedback :-)
Mir ist gerade einen Qualitätsunterschied zwischen einer älteren Version (2010/05/06) und der Aktuellen aufgefallen.
Wenn ich ein Bild mit der Version vom 2010/05/06 verkleinere ist die Bildqualität gut und sieht so aus http://gabaglio.com/images/2011/schnappschuss_0117173107.jpg , wenn ich das Bild aber mit der aktuellen Version verkleinern hat das Bild Streifen (Sichtbar im Himmel). http://gabaglio.com/images/2011/schnappschuss_0117172718.jpg
Dies ist wohl nicht beabsichtigt :-)
@Orlando
Kannst du mir das Originalbild und deinen Code zukommen lassen?
@sprain
Sind per Mail gesendet.
@all
Das “Problem” bei Orli war, dass er mit der Qualitätseinstellung der JPEG-Speicherung gespielt hat, diese im Skript veränderte und sich nicht mehr daran erinnern konnte :) Problem gelöst!
Muss mich zunächst einigen Vorrednern anschließen: Sehr gute Arbeit! Bin begeistert.
Allerdings habe ich eben ein Problem festgestellt: In der resize-Methode werden im Zweig zu “crop” für den Parameter $cropAreaBottomTop nur die Werte “b” und “c” abgefragt, nicht aber “t”, wie es im Hotdog Beispiel 3 verwendet wird.
Analog für Parameter $cropAreaLeftRight.
Oder habe ich was übersehen? Bei mir funktioniert “crop” mit “t” nämlich leider nicht…
Kopf -> Tischplatte.
Mein Problem war kein Fehler in der Klasse. Die Werte zum Zuschneiden bei “crop” mit “t” bzw. “r” werden ja mit 0 initialisiert, sodass eine extra Abfrage dieser Fälle nicht nötig ist.
Mein Fehler lag viel mehr am Skript das die Klasse genutzt hat (dort waren die Parameter für resize() falsch gesetzt).
Unterstreicht nur nochmal meine Meinung aus dem vorherigen Kommentar: große Klasse diese Klasse :)
@Markus
Schön, wenn sich Probleme von selbst lösen. Also für mich… ;)
Werde mich demnächst mal in den Code ein wenig einlesen.
Meine Frage vorab: Wie handelt die Klasse Fehler?
Ist etwas möglich wie:
if (!$image->resize(300, 100, “crop”)) {
// if there was an error, let’s see what the error is about
switch ($image->error) {
case 1:
echo ‘Source file could not be found!’;
break;
case 2:
echo ‘Source file is not readable!’;
break;
case 3:
echo ‘Could not write target file!’;
break;
case 4:
echo ‘Unsupported source file format!’;
break;
case 5:
echo ‘Unsupported target file format!’;
break;
case 6:
echo ‘GD library version does not support target file format!’;
break;
case 7:
echo ‘GD library is not installed!’;
break;
}
@Matthias
Du darfst soetwas gerne einbauen :)
Na dann schau ich mal, ob ich das demnächst mal hinbekomme ;-)
Wir suchen aktuell eine gute Image-Klasse für Lepton CMS und diese hier gefällt mir persönlich recht gut…
Lediglich das Errorhandling muss ich mir eben mal ansehen ;-)
Die Klasse hat die Abstimmung gewonnen und wird nun für LEPTON CMS eingebunden. Gratuliere! Du hast harte Konkurrenz ausgestochen!
Ich habe eben ein kleines Problem mit readImageInfo() bei einem PNG festgestellt. Dort war der Array-Index “channel” nicht belegt. Korrektur:
$this->imageInfo["channels"] = ( isset($data["channels"]) ? $data["channels"] : NULL );
Ich forke das mal bei GitHub und schicke Dir einen Pull Request. Error handling werden wir sicherlich auch noch einbauen.
Hast Du evtl. auch eine Lösung für das Watermark-Problem bei transparenten Bildern? (Idee im Kopf, aber aus Zeitgründen nicht eingebaut oder so?)
@WebBird
Cool, freut mich!
Euren Bugfix hab ich gemerged.
Was das Watermark-Problem angeht hab ich im Moment leider keinen Lösungsansatz auf Lager. Hab mich aber auch schon lange nicht mehr darum gekümmert…
Danke für die gute Arbeit!
Ich habe bei GitHub einige Änderungen bezüglich der Watermark-Geschichte eingestellt. Kannst Du Dir ja mal angucken.
Very nice and handy class.
Well done, mate.
Thanks for sharing the great work.
Danke für die tolle Klasse, ich verwende sie in verschiedensten meiner Web-Projekte.
Heute habe ich ein Problem mit transparenten PNGs entdeckt – nach dem Bearbeiten mit deiner Klasse hatten die Bilder alle einen schwarzen Hintergrund. Wahrscheinlich ist das zwar nicht der perfekte Bugfix, aber durch den folgenden Block in Zeile 248 (im “//Let’s get it on, create image!” Block nach der ersten Zeile eingefügt) wird das Problem gelöst:
if ($image_save_func == “ImagePNG”) {
imagesavealpha($imageC, true);
$trans_colour = imagecolorallocatealpha($imageC, 0, 0, 0, 127);
imagefill($imageC, 0, 0, $trans_colour);
}
@macwinnie
Danke für den Hinweis. Ich werde dies bei Gelegenheit mal noch näher prüfen.
Hallo,
vielen Dank für deine Arbeit, prima Sache.
Ich beiss mir gerade die Zähne an einer bestimmt simplen Sache aus:
Das Bild soll unter gleichem Namen gespeichert werden.
Egal was ich mache, immer entsteht
bild.jpg.jpg
Habe es auch hiermit versucht:
$image->save($bild,”$dirname/thumbs/”,”");
Damit müsste die Klasse doch die Extension “übergehen”?
(Gut, ich kann ja auch vorher die .jpg wegmachen, aber das ist nicht schön …)
So, feiert erstmal ins neue Jahr. Die Sache hier hat noch bis morgen Zeit ;-)
Danke
@Jan
Die Klasse ist darauf ausgelegt, die Extension selbst zu setzen. So wird vermieden, dass eine falschen Extension geschrieben wird.
Am Besten entfernst du die Extension einfach aus dem Filenamen vor dem Aufrufen der save-Methode.