Vorschaubild-Klasse

Ich habe ja bereits eine Anleitung zum Erstellen von Vorschaubildern in PHP geschrieben, ich selbst verwende dazu eine selbst geschriebene Klasse.

Was die Klasse kann

  • Vorschaubilder von beliebiger Größe erstellen
  • Das Seitenverhältnis der Vorschaubilder anpassen wenn erforderlich und gewünscht
  • Einen Rahmen um das Vorschaubild zeichnen.
  • Ein kleines Kästchen mit Informationen wie z.B. Dateigröße, Dateityp, o.Ä. oben/unten anzeigen.
  • Die Transparenz und die Farben des Kästchens und der Schrift die Farbe des Hintergrunds und des Rahmens sowie die Dicke von letzterem lassen sich einfach ändern/anpassen.
  • Bei Fehlern werden Exceptions geworfen.

Die Klasse

<?php
 
class thumbnail_exception extends Exception {};
 
class thumbnail {
	protected $image_width = 0;				/* Width of the source image */
	protected $image_height = 0;				/* Height of the source image */
	protected $image_handle;				/* Handle of the source image */
	protected $image_path = "";				/* Path of the source image */
	protected $image_type;					/* Image type of the source image */
 
	protected $thumbnail_path = "";				/* Path where the thumbnail should be saved */
	protected $thumbnail_width = 100;			/* Desired thumbnail width */
	protected $thumbnail_height = 100;			/* Desired thumbnail height */
	protected $thumbnail_type = self::IMAGETYPE_BY_SOURCE;	/* Desired image type of the thumbnail */
	protected $thumbnail_final_width = 100;			/* Final width of the thumbnail picture */
	protected $thumbnail_final_height = 100;		/* Final height of the thumbnail picture */
 
	protected $border_size = 0;				/* Border size */
	protected $border_color = "#000";			/* Border color */
 
	protected $background_color = "#ccc";			/* Background color */
 
	protected $resize = true;				/* Should the thumbnail be resized according to width:height ratio? */
 
	protected $quality = self::RESAMPLE;			/* Quality of the thumbnail */
 
	protected $info_position = self::NO_INFO;		/* Position of the information box, or if it should not be drawn "NO_INFO" */
	protected $info_box_color = "#000";			/* Color of the background of the information box */
	protected $info_text_color = "#FFF";			/* Text color of the information box */
	protected $info_text = "";				/* Text of the information box */
	protected $info_transparency = 0;			/* Transparency of the information box */
	protected $info_size = 16;				/* Height of the information box */
 
	const RESIZE = 1;					/* Only resize, do not resample */
	const RESAMPLE = 2;					/* Resample the image, slower but better quality */
 
	const IMAGETYPE_BY_SOURCE = 100;			/* Choose thumbnail image type like source image type */
 
	const NO_INFO = 0;
	const TOP = 1;
	const BOTTOM = 2;
 
	public function get_width() {
		return $this->image_width;
	}
 
	public function get_height() {
		return $this->image_height; 
	}
 
	public function get_type() {
		switch($this->image_type) {
			case IMAGETYPE_GIF:  return "GIF";
			case IMAGETYPE_JPEG: return "JPG";
			case IMAGETYPE_PNG:  return "PNG";
			default: throw new thumbnail_exception("Image type not supported!");
		}
	}
 
	public function get_filesize() {
		$fsize = filesize($this->image_path);
		/* The filesize function returns the file size in bytes. -> convert value to Kibi/Mebibytes */
		if ($fsize >= 1048576) 
			return round($fsize / 1048576, 2) . " MiB";
		else
			return round($fsize / 1024, 2) . " KiB";
	}
 
	public function set_image($path) {
		$this->image_path = $path;
 
		$info = getimagesize($path);
 
		if ($info == false || ($info[0] + $info[1]) == 0)
			throw new thumbnail_exception("Image could not be read, is not an image or image type is not supported!");
 
		$this->image_height = $info[1];
		$this->image_width  = $info[0];
		$this->image_type   = $info[2];
 
		switch($this->image_type) {
			case IMAGETYPE_GIF:  $this->image_handle = imagecreatefromgif($path); break;
			case IMAGETYPE_JPEG: $this->image_handle = imagecreatefromjpeg($path); break;
			case IMAGETYPE_PNG:  $this->image_handle = imagecreatefrompng($path); break;
			default: throw new thumbnail_exception("Image type not supported!");
		}
 
		return $this;
	}
 
	public function set_information_box($position, $text = "", $box_color = "#000", $text_color = "#FFF", $trans = 0) {
		switch ($position) {
			case self::NO_INFO: $this->info_position = self::NO_INFO; return $this;
			case self::TOP:     $this->info_position = self::TOP; break;
			case self::BOTTOM:  $this->info_position = self::BOTTOM; break;
			default: throw new thumbnail_exception("Position must be NO_INFO, TOP, or BOTTOM.", 1);
		}
 
		/* Checks if the desired information text fits into the thumbnail. */
		if ($this->calculate_info_text_pixels($text) > ($this->thumbnail_width - ($this->border_size * 2)))
			throw new thumbnail_exception("Text "$text" doesn't fit into image.", 3);
 
		$this->info_text = $text;
		$this->info_box_color = $box_color;
		$this->info_text_color = $text_color;
 
		if ($trans < 0 || $trans > 127)
			throw new thumbnail_exception("Transparency must be a number between 0 and 127.", 2);
		$this->info_transparency = $trans;
 
		return $this;
	}
 
	public function set_dimensions($width, $height) {
		if ($width <= 0 || $height <= 0)
			throw new thumbnail_exception("The desired thumbnail width and height must be above 0.");
 
		$this->thumbnail_width  = $width;
		$this->thumbnail_height = $height;
 
		return $this;
	}
 
	public function set_image_type($type) {
		if ($type != self::IMAGETYPE_BY_SOURCE && $type != IMAGETYPE_GIF && $type != IMAGETYPE_PNG && $type != IMAGETYPE_JPEG)
			throw new thumbnail_exception("Image type not supported.");
		$this->thumbnail_type = $type;
 
		return $this;
	}
 
	public function set_destination_path($path) {
		$this->thumbnail_path = $path;
 
		return $this;
	}
 
	public function set_border($size, $color) {
		if ($size < 0)
			throw new thumbnail_exception("Border size must be 0 or higher.");
 
		$this->border_size = $size;
		$this->border_color = $color;
 
		return $this;
	}
 
	public function set_resize($resize) {
		$this->resize = $resize;
 
		return $this;
	}
 
	public function set_background_color($color) {
		$this->background_color = $color;
 
		return $this;
	}
 
	public function set_quality($quality) {
		$this->quality = $quality;
 
		return $this;
	}
 
	public function create_thumbnail() {
		/* Remember values, because if the image gets resized, they would change. */
		$tw_backup = $this->thumbnail_width;
		$th_backup = $this->thumbnail_height;
 
		/* Calculate the final dimensions of the resized image. These values are not the final size of the thumbnail picture,
		 * only the dimensions of the resized image! */
		$total_height = $this->thumbnail_height - ($this->border_size * 2);
		$total_width = $this->thumbnail_width - ($this->border_size * 2);
 
		/* If the information box is drawn, and it is drawn not inside the thumbnail picture, adjust height value. */
		if ($this->info_position != self::NO_INFO && $this->info_transparency == 0) 
			$total_height -= $this->info_size;
 
		/* If the source image is wider than high, recalculate final height to fit aspect ratio. Otherwise recalculate
		 * the width. */
		if ($this->image_width > $this->image_height) {
			$this->thumbnail_final_width = $total_width;
			$this->thumbnail_final_height = round($this->image_height / ($this->image_width / $total_width));
		}
		else {
			$this->thumbnail_final_height = $total_height;
			$this->thumbnail_final_width  = round($this->image_width / ($this->image_height / $total_height));
		}
 
		/* If the thumbnail should get resized according to the aspect ratio (so there is no unfilled space or background
		 * in the final thumbnail) the values for the final size of the thumbnail picture get adjusted. */
		if ($this->resize) {
			$this->thumbnail_width = $this->thumbnail_final_width + (2 * $this->border_size);
			$this->thumbnail_height = $this->thumbnail_final_height + (2 * $this->border_size);
 
			/* Again, if the information box is drawn, and it is drawn not inside the thumbnail picture, adjust height 
			 * value. */
			if ($this->info_position != self::NO_INFO && $this->info_transparency == 0) 
				$this->thumbnail_height += $this->info_size;
		}
 
		$this->thumbnail_handle = imagecreatetruecolor($this->thumbnail_width, $this->thumbnail_height);
 
		$this->draw_background();
		$this->draw_thumbnail();
		$this->draw_border();
		$this->draw_info();
 
		if ($this->thumbnail_type == self::IMAGETYPE_BY_SOURCE) $this->thumbnail_type = $this->image_type;
		switch($this->thumbnail_type) {
			case IMAGETYPE_PNG: imagepng($this->thumbnail_handle, $this->thumbnail_path); break;
			case IMAGETYPE_GIF: imagegif($this->thumbnail_handle, $this->thumbnail_path); break;
			case IMAGETYPE_JPEG: imagejpeg($this->thumbnail_handle, $this->thumbnail_path); break;
		}
 
		/* Now restore the desired thumbnail dimensions, this is needed if more than one thumbnail is generated using the same
		 * class instance. */
		$this->thumbnail_width = $tw_backup;
		$this->thumbnail_height = $th_backup;
	}
 
	protected function draw_border() {
		$border_color = $this->allocate_color_from_hex($this->border_color);
		for ($i = 0; $i < $this->border_size; $i++)
			imagerectangle($this->thumbnail_handle, $i, $i, $this->thumbnail_width - (1 + $i), $this->thumbnail_height - (1 + $i), $border_color);
 
	}
 
	protected function draw_thumbnail() {
		if ($this->info_transparency == 0 && $this->info_position != self::NO_INFO) { $tr = $this->info_size; }
		else { $tr = 0; }
 
		$sx = ($this->thumbnail_width - $this->thumbnail_final_width) / 2;
		$sy = ($this->thumbnail_height - $this->thumbnail_final_height - $tr) / 2;
 
		if ($this->info_position == self::TOP)
			$sy += $tr;
		var_dump($sx,$sy,$this->thumbnail_height, $this->thumbnail_final_height);
		switch($this->quality) {
			case self::RESIZE: $this->image_resize($sx, $sy); break;
			case self::RESAMPLE: $this->image_resample($sx, $sy); break;
			default: throw new thumbnail_exception("Quality can only be one of these: QUALITY_RESIZE, QUALITY_RESAMPLE.");
		}
	}
 
	protected function draw_background() {
		imagefill($this->thumbnail_handle, 1, 1, $this->allocate_color_from_hex($this->background_color));
	}
 
	protected function draw_info() {
		/* Don't draw information box if it would take over the half of the image. */
		if (($this->thumbnail_height / 2) <= $this->info_size)
			return;
 
		switch ($this->info_position) {
			case self::NO_INFO: return;
			case self::TOP:    $position_y = $this->border_size; break;
			/* minus border size (the border at the top), the size of the info bar and 1 (because drawing starts at position 0) */
			case self::BOTTOM: $position_y = $this->thumbnail_height - ($this->border_size + $this->info_size) - 1;
		}
 
		$position_x = $this->border_size;
		$text_x = round((($this->thumbnail_width - ($this->border_size * 2)) - ($this->calculate_info_text_pixels($this->info_text))) / 2);
 
		/* Activate alpha blending when transparency is used. */
		if ($this->info_transparency > 0)
			imagealphablending($this->thumbnail_handle, true);
 
		$bkg_color =  $this->allocate_color_from_hex($this->info_box_color, $this->info_transparency);
		$text_color = $this->allocate_color_from_hex($this->info_text_color, $this->info_transparency);
 
		imagefilledrectangle($this->thumbnail_handle, $position_x, $position_y, 
				     $this->thumbnail_width - $position_x - 1, $position_y + $this->info_size, $bkg_color);
		imagestring($this->thumbnail_handle, 3, $text_x + 1, $position_y + 2, $this->info_text, $text_color);
	}
 
	protected function image_resize($sx, $sy) {
		imagecopyresized($this->thumbnail_handle,
				 $this->image_handle,
				 $sx,
				 $sy, 0, 0,
				 $this->thumbnail_final_width,
				 $this->thumbnail_final_height,
				 $this->image_width, $this->image_height);
	}
 
	protected function image_resample($sx, $sy) {
		imagecopyresampled($this->thumbnail_handle,
				   $this->image_handle,
				   $sx,
				   $sy, 0, 0,
				   $this->thumbnail_final_width,
				   $this->thumbnail_final_height,
				   $this->image_width, $this->image_height);
	}
 
	function allocate_color_from_hex($hex, $trans = 0) {	
		if (strlen($hex) == 4) $hex = '#' . $hex[1] . $hex[1] . $hex[2] . $hex[2] . $hex[3] . $hex[3];
 
		$red   = hexdec(substr($hex, 1, 2));
		$green = hexdec(substr($hex, 3, 2));
		$blue  = hexdec(substr($hex, 5, 2));
 
		if ($trans == 0) return imagecolorallocate($this->thumbnail_handle, $red, $green, $blue);
		return imagecolorallocatealpha($this->thumbnail_handle, $red, $green, $blue, $trans);
	}
 
	function calculate_info_text_pixels($text) {
		return strlen($text) * 7;
	}
}
 
?>

Verwendung

Hier ein kleines Beispiel das zeigt wie man ein Vorschaubild mit einem Rahmen und ohne Info-Kästchen erstellt. Zu erst wird eine neue Instanz der thumbnail-Klasse erstellt, dann wird mit den set_-Befehlen festgelegt wo das Vorschaubild gespeichert wird, wie der Rahmen aussehen soll etc.

<?php
 
/* Ein einfaches Vorschaubild ohne Info-Box erstellen */
require_once("thumbnail/thumbnail.class.php");
 
try {
	/* Eine neue Instanz der Vorschaubild-Klasse erstellen */
	$thumb = new thumbnail();
 
	/* Festlegen von welchem Bild ein Vorschaubild erstellt werden soll */
	$thumb->set_image("ausgangsbild.png")
 
	/* Wo das Vorschaubild gespeichert werden soll */
	      ->set_destination_path("vorschaubild.png")
 
	/* 1 Pixel breiter schwarzer (#000) Rahmen */
	      ->set_border(1, "#000")
 
	/* Das Bild soll schnell aber mit niedrigerer Qualitaet verkleinert werden */
	      ->set_quality(thumbnail::RESIZE)
 
	/* Legt fest in welchem Bildformat (PNG, JPEG, GIF) das Vorschaubild
	 * gespeichert werden soll, bei IMAGETYPE_BY_SOURCE wird das Bildformat
	 * vom Quellbild genommen */
	      ->set_image_type(thumbnail::IMAGETYPE_BY_SOURCE)
	/* Keine Info-Box anzeigen */
	      ->set_information_box(thumbnail::NO_INFO)
	/* Vorschaubild erstellen */
	      ->create_thumbnail();
}
catch (thumbnail_exception $e) {
	/* Fehler ausgeben falls einer aufgetreten ist */
	echo "Fehler: " . $e->getMessage();
}
 
?>

Wenn bei der Erstellung des Vorschaubildes irgendetwas schief läuft wird eine Exception geworfen, die Fehlermeldung kann dann per getMessage() abgerufen werden.

Zu den einzelnen Funktionen/Einstellungsmöglichkeiten:

set_image($pfad)

Bestimmt das Bild, von dem ein Vorschaubild erstellt werden soll. Der Parameter $pfad gibt den Pfad zum Bild bzw. den Dateinamen an.

set_dimensions($breite, $hoehe)

Legt fest wie groß das Vorschaubild sein soll.

set_image_type($bildformat)

Diese Funktion legt fest in welchem Format das Vorschaubild abgespeichert werden soll, mögliche Bildformate sind:

  • IMAGETYPE_GIF (.gif)
  • IMAGETYPE_PNG (.png)
  • IMAGETYPE_JPEG (.jpg/.jpeg)
  • IMAGETYPE_BY_SOURCE (Das Vorschaubild wird im selben Format wie das Ausgangsbild abgespeichert)

Andere Bildformate als GIF/PNG/JPEG werden nicht unterstützt.

set_destination_path($pfad)

Legt fest unter welchem Dateinamen/Pfad das Vorschaubild abgespeichert werden soll.

set_border($dicke, $farbe)

Mit set_border lässt sich einstellen ob ein Rahmen gezeichnet werden soll (Kein Rahmen: $dicke = 0), wie dick er sein soll und welche Farbe er hat. Die Farbe wird als HTML-Farbcode angegeben, z.B. #000000 für Schwarz.

set_resize($anpassen)

Das Vorschaubild kann in seiner Größe an das Seitenverhältnis angepasst werden. Ist das Ausgangsbild z.B. sehr breit aber hat nur eine geringe Höhe, wird die Höhe des Vorschaubildes entsprechend angepasst (set_resize(true)), ansonsten wird die freie Fläche mit der Hintergrundfarbe aufgefüllt (set_resize(false)).

set_background_color($farbe)

Legt die Hintergrundfarbe vom Vorschaubild fest (siehe set_resize).

set_quality($qualitaet)


PHP bietet zwei Funktionen zum vergrößern/verkleinern von Bildern an, einmal imagecopyresized und einmal imagecopyresampled. Letzteres erzeugt schönere Ergebnisse, ist aber ungefähr 400% langsamer. set_quality legt fest ob imagecopyresized (thumbnail::RESIZE) oder imagecopyresampled (thumbnail::RESAMPLE) verwendet werden soll.

set_information_box($position, $text, $kaestchenfarbe, $textfarbe, $transparenz)

Man kann am unteren oder oberen Rand des Vorschaubilds ein kleines Kästchen mit Informationen über das Bild anzeigen lassen. $position legt fest ob das Kästchen oben (thumbnail::TOP), unten (thumbnail::BOTTOM) oder gar nicht (thumbnail::NO_INFO) angezeigt werden soll. $text ist der Text der im Kästchen stehen soll, ist dieser zu lang und passt nicht ins Bild wird eine Exception geworfen. Meistens will man im Kästchen Informationen über das Ausgangsbild anzeigen, folgende 4 Funktionen erleichtern das:

  • get_width – Gibt die Breite des Ausgangsbilds zurück
  • get_height – Gibt die Höhe zurück
  • get_type – Gibt das Bildformat zurück (GIF/PNG/JPG)
  • get_filesize – Die Dateigröße in KiB/MiB (z.B. “123 KiB”, “2.45 MiB”)

$kaestchenfarbe und $textfarbe bestimmen die Farbe, $transparenz die Transparenz des Kästchens/der Schrift. Die Farben werden als HTML-Farbcodes angegeben (z.B. #123456), die Transparenz als Zahl zwischen 0 (keine Transparenz) und 127 (100% transparent/unsichtbar).

create_thumbnail()

Erstellt das Vorschaubild und speichert es unter der mit set_destination_path angegebenen Ziel-Adresse ab.

Abschließendes

Wenn ihr die Klasse gebrauchen könnt, könnt ihr sie gerne verwenden. Ich übernehm aber keine Garantie dafür das sie fehlerfrei ist. ;)

Über Kritik/Verbesserungsvorschläge würde ich mich freuen, schreibt doch einfach einen Kommentar.

Informationen

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Keine Bewertung bis jetzt)
Loading ... Loading ...
Schlagwörter: , ,
Ansichten: 809

Kommentare

Keine Kommentare bis jetzt.

Kommentar schreiben

XHTML: Folgende Elemente sind erlaubt: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Angetrieben durch Wordpress Thema erstellt von Antu